public static function getRelativePath($from, $to)
{
// Windows FTW!
$from = self::windowsFix($from);
$to = self::windowsFix($to);
$from = preg_replace('~([^/]*)/+([^/]*)~', '$1/$2', $from);
$to = preg_replace('~([^/]*)/+([^/]*)~', '$1/$2', $to);
$from = rtrim($from, '/');
$to = rtrim($to, '/');
$from = explode('/', $from);
$to = explode('/', $to);
$from = self::realpath($from);
$to = self::realpath($to);
$depthOfCommonPath = self::countCommonDepth($from, $to);
$relPath = array_slice($to, $depthOfCommonPath);
// get number of remaining dirs up to $from
$remaining = count($from) - $depthOfCommonPath;
// add .. up to first matching dir
$totalLengthOfRelativePath = count($relPath) + $remaining;
$relPath = array_pad($relPath, $totalLengthOfRelativePath * -1, '..');
return implode('/', $relPath);
}