Tine 2.0 – #2 The Update

Many problems occur during an update, here I’ll show you my workflow.

Some basic rules:

  1. Backup your database before updating, if there goes something wrong, there is a way back.
  2. Backup your files directory, since 2017 Tine 2.0 stores there internals as well as your files.
  3. Keep your old source until you’ve verified your new Tine 2.0, it’s easier to switch back if you keep did that.

That’s how my structure looks like:

tine.example.com is a link to the latest Tine 2.0 source and as you see it’s actually pointing to 2018.02.1, but I’d like to update to 2018.02.2. Unzip the new Tine 2.0 into 2014.09.2 so the index.php is right underneath 2018.02.2.

Use cp /2018.02.1/config.inc.php /2018.02.2 and cp /2018.02.1/.htaccess /2018.02.2 in case you are using apache2.

Now get into the new sources directory and run php setup.php --update to start the update process. It should output not that much, just which application where updated.

It’s time to publish the new version to the world with ln -sfT /2018.02.2 /tine.example.com.

It’s good practise to enable the logging in your config.inc.php while updating to make sure there occured nothing bad.

You’ll probably run into problems with the cache, you could solve this by delete everything inside the caching directory.

For example: rm -rf tine_cache/*!

Have fun and enjoy your Tine 2.0 installation. 🙂

What is a bitmask?

Saw stuff like error_reporting(E_ERROR | E_WARNING | E_PARSE); or heard about bitmasks and got confused how it actually works? To my shame I never looked it up in like 12 years of programming until now.

What it actually is, is a quite efficient way to define for example grants for a user or which features are enabled for an application. It’s also quite old school but often seen and still in use.

At this point I’d suggest you to also open the PHP documentation where they explain all existing bitwise operators. I created some examples here to make it easier to understand and to visualise what is happening.

So what we’ve learned:

  • We have a 4 bits and we assign a meaning to each of them
  • We can individually switch single bits to express a state
  • Bitwise operations are supposed to be very fast and efficient
  • Use only numbers with a power of 2, otherwise we would mess up the bitmask because the binary system represent a number which is not of the power of 2 by two or more bits
  • Using a bitmask for a simple ACL system and putting each grant into a const might even make it readable and easy to work with

Would I use it? Maybe or maybe not it really depends on what I exactly need. It’s fast and solid when done right but will become messy when it’s getting much more complex. But in case you run into legacy code as I did this might help you to understand it.

Scale NSImage up into NSImageView

Interpolated image

Imagine having a 10*10 NSImage you want to scale up in an NSImageView to like 100*100. The result will look pretty blurred. That’s caused by the image interpolation of NSImageView which is interpolating the image.

This might be fine for most things like photos, when scaling them down or up. But my situation were different, I wanted to zoom into it to visualise the pixels.

It took me many hours to find out that most proposed solutions like setting the magnificationFilter to kCAFilterNearest on the NSImageView’s layer are just not working. Maybe they do, somehow, I couldn’t make them work. If someone knows how, I would be glad to learn.

Not interpolated image

So back to the topic, once I figured out that interpolation was done by the NSImageView I simply implemented my own NSImageView and disabled the image interpolation on it’s current NSGraphicsContext.

For me it’s just fine, because I planed anyway to extend NSImageView for my needs. I hope this will save someone some time.

PHP proper string to boolean casts

Casting a string to a boolean can be tricky but it’s actually super easy. First of all never use boolval or casts like (bool) $string. It will never work or won’t result in what you believe it will. There are good reasons why it’s like that and I’m aware that other languages cope that with ease.

Just use filter_var which can properly convert strings into booleans. filter_var can do a lot more, but for booleans I use it all the time. Also check out if your framework provides something cool, some does, some doesn’t.

Just a common mistake I’ve often seen. Cheers and have fun coding!

Tine 2.0 – #1 The Installation

First of all it’s pretty easy and in this guide I’ll mention all important steps to succeed and avoid all known pitfalls. Second of all, this guide represents a best practise installation of Tine 2.0 and you should be able to achieve best results with this guide.

Please keep in mind, that you and only you are in charge of your installation. You are responsible for reliability and safety. If you don’t comply with that you should consider to use a hosted solution!

This guide was last updated at 26th February, 2018.

26.02.2018 – Add Cron Job – thanks estradis


Tine 2.0 is a PHP based application which runs great with just a MariaDB. But you clearly improve your experience with setting up Redis as a session storage, cache and queue worker.

I hereby suggest PHP 7 or higher due to it’s performance improvements.

Tine 2.0 runs great with PHP 5.5 + but  7.0+ is a better choice.

For PHP you’d like to make sure, that you have the following extensions enabled: ctype, date, xml, dom, SimpleXML, gd, hash, iconv, json, mysql, pdo_mysql, SPL and zip. Those packages are pretty common and should be available on all linux distributions.

Tine 2.0 is optimised for Mysql/MariaDB, I wouldn’t suggest to use PostgreSQL or Oracle, especially because the PostgreSQL support is about to be probably dropped in the future and a migration is not that easy.

The best experience can be achieved with MariaDB 5.5.4+. We are using some features of 5.5.4, if you don’t have or your provider doesn’t support it, it’s not a game breaker, but the fallbacks are less performant.

About the webserver, nginx or apache2 are both working great and the important rewrite rules are available for both. This is just up to you!

Find the right package

All packages can be found on Github, the most relevant package is called All-in-One and ships the whole thing like Addressbook, Calendar, Mail and even more. Literally everything a groupware should offer.

We also have repositories for some distributions, I personally prefer the manual installation which is describe in this guide.

Preparing the setup

At this point I assume that you have a running server, with properly configured database, web server and application server.

Tine 2.0 need some rewrite rules to support activesync and *dav.

For apache2 put this into your  .htaccess file:


For nginx you need to put it into your host configuration:

This is the minimal config for nginx, you can tune nginx a lot of improve the performance of Tine 2.0! But that’s up to you.

The next step is to unzip the All-in-One package into your webroot.

The setup

This step expects your web server to be set up with all required rewrite rules as well as database server and redis (optional). 

Tine 2.0 needs some folders writable to fully operate. This folders are cache, files, session and temp. All these folders shouldn’t be accessible from the web. Only your application server needs to write and read there.

cache and session can be replaced by redis which improves the overall experience a lot!

Exposing those folders to the web can cause severe vulnerabilities to your installation. I suggest to place them somewhere out of your web root.

For example you can create a dedicated folder for Tine 2.0 in /srv or somewhere else and make it write and readable only to your application server which is php-fpm in best case.

You’ll find a file called config.inc.php.dist in your webroot, you need to rename it to config.inc.php to proceed. Once done you edit it and fill any username and password for the Tine 2.0 setup interface. Keep in mind, that the setup page will be available after installation and you should chose a good password.

Fig 1. Tine 2.0 Setup Login

Once done navigate with your web browser to https://<your url>/setup.php. You should be able to see a login like in Fig 1.

Once logged in you need to accept the terms and conditions to proceed. On the next page Tine 2.0 will check your server installation for compatibility. If everything is green you should be able to proceed.

The configuration

Tine 2.0 offers many configuration options and some of them are more important than others. At this point we’ll go through the more important and useful settings.

Config Manager

Fig 2. Config Manager example

What you need to configure is:

  • Database
  • Caching
  • Session
  • Temporary files
  • Filestore directory

What you can configure is:

  • Logging
  • Queue

I would suggest you to configure queue as well, it can improve the userexperience and improves the performance! To use the queuing feature in Tine 2.0 you need a redis server.

Attention: The queue worker requires an additional worker running on your server which is not covered by this tutorial yet!

In theory there is no real need to set a session path, PHP should know itself where to store them. But I had problems without an explicit session path.

If you decided to use redis, you should set caching and session to redis otherwise you should find a save place on yo

ur server and create folders for caching, temporary files and filestore directory. Make sure those folders are writable by the application server and are not exposed to the www.


Fig 3. Authentication/Accounts example

Tine 2.0 is mighty. Really. Tine 2.0 can integrate into several authentication backends and is able to interact with your mailserver. I won’t cover all of those aspects in this tutorial.

Important sections are Authentication provider and Accounts storage, first one decides if the login is valid and second one where the accounts are stored. I use IMAP as an authentication provider but Tine 2.0 can also use itself. Most people would like to set both to SQL and just proceed.

IMAP becomes interesting if you run Tine 2.0 for example for your family and everyone has a family mail account. Or same with a small company.

In case you have LDAP you can also set both to LDAP which might be cool for companies.

Asynchronous jobs

Some features require a cron job to work properly. For example some calendar notifications using the cron to mail users.

The cron job:

Please make sure, that the paths are matching your installation!


Fig 4. Email example

You should fill SMTP and IMAP with mailserver information, Tine 2.0 will use it to send event invitations and so on!

Use system account comes handy when you have one mail account per user and all have the same mail server. When set to true, all your users will have a fixed mail account. That’s super useful for when you don’t want to set up all user profiles yourself.

In case your mail server provides sieve, you can set it up as well. Tine 2.0 offers a sieve client for all users, so they are able to define vacation notices and server sided filter rules.

Application manager

Now it’s your turn to decide which applications you like to have. I would suggest for a fully featured setup:

  • Addressbook
  • Calendar
  • ActiveSync
  • Felamimail
  • Filemanager

And congratulations you are done. No have fun and enjoy Tine 2.0! 🙂

Seek help or want to contribute?

There is a community page with all relevant resources! 🙂


First of all I’d to apologise to all people reading me for this hard cut, but I considered to change this site for a long time and today I did.

In the future I’ll restore many of my old posts, especially all tutorials and useful articles which brought you here in the past.

And on top of it I plan to bring a series of some nice and useful tutorials about software I personally use and/or I’m personally or professionally involved in.

To my Tine 2.0 related readers: I’m updating my tutorials and will publish them within the next few days!

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.