<?php
function sitematch($key,$site){
    // Add double slashes to key and site if no scheme is set.
    // Basically: if no double slashes present before any dots,shashes or @s.
    if(!\preg_match_all('#^[^./@]*?//#',$key )) {
        $key = "//".$key;
    }
    if(!\preg_match_all('#^[^./@]*?//#',$site)) {
        $site = "//".$site;
    }
    // Use parse_url() to split path and host.
    $keyurl = (object)\parse_url($key);
    $siteurl = (object)\parse_url($site);

    // No match if host is empty on key or site
    if (empty($keyurl->host) || empty($siteurl->host)) {
        return false;
    }

    if ($keyurl->host == "*") {
        // * matches all
        return true;
    }

    // First match the host part.
    $keyparts = \array_reverse(\explode(".",$keyurl->host));
    $siteparts = \array_reverse(\explode(".",$siteurl->host));

    // Trim starting www from both parts, since site.domain and www.site.domain should be treated as the same.
    if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts,$x);}
    if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts,$x);}

    for ($i = 0; $i < count($keyparts); $i++) {
        // No match if the site does not have a part, but the key does. Unless the key part is *
        if (!isset($siteparts[$i]) ) {
            if($keyparts[$i] != "*") {
                return false;
            } else {
                $i++; //increment $i by one before break, to make sure the comparison following this loop holds.
                break; // Stop comparison. Host part matches.
            }
        }

        // Now do a proper case insensitive check for matching.
        // Uses fnmatch to easily handle shell type wildcards.
        if ( ! \fnmatch($keyparts[$i],$siteparts[$i],\FNM_CASEFOLD)) {
            return false;
        }
    }
    // Fail if the site has a deeper subdomain than the key, unless the deepest key subdomain is *
    if ($keyparts[$i-1] != '*' && count($siteparts) > ($i)) {
        return false;
    }

    // If we made it here then the host part matches. Now check the path.
    // If path is /*, matches all subpaths including /
    $keypath = empty($keyurl->path)?"/":$keyurl->path;
    $sitepath = empty($siteurl->path)?"/":$siteurl->path;
    
    // Trim trailing / from both paths before comparison
    if (\strlen($sitepath) > 1) {
        $sitepath = \rtrim($sitepath,"/");
    }
    if (\strlen($keypath) > 1) {
        $keypath = \rtrim($keypath,"/");
    }

    // Do a case insensitive fnmatch on the site so wildcards are matched too.
    return \fnmatch($keypath,$sitepath,\FNM_CASEFOLD);
}

$tests = [
    ["*", "https://www.miqra.nl"],
    ["*/*", "https://www.miqra.nl"],
    ["*", "https://clients.openedu.nl/fith"],
    ["clients.openedu.nl/fith", "https://clients.openedu.nl/fith/"],
    ["clients.openedu.nl/fith/", "https://clients.openedu.nl/fith"]
];

foreach($tests as $test) {
    [$key, $site] = $test;
    print("Checking key '{$key}' on site '{$site}': " . (sitematch($key,$site)?"MATCH":"FAIL") . "\n");
}