public function getLink($bAbsolute = false, $sAnchor = null, $aOptionalParameters = array(), \TdbCmsPortal $portal = null, \TdbCmsLanguage $language = null)
    {
        // if no category is given, fetch the first category of the article
        $shopService = $this->getShopService();
        $oShop = $shopService->getActiveShop();
        $sCategoryId = null;
        if (true === array_key_exists(TdbShopArticle::CMS_LINKABLE_OBJECT_PARAM_CATEGORY, $aOptionalParameters)) {
            $sCategoryId = $aOptionalParameters[TdbShopArticle::CMS_LINKABLE_OBJECT_PARAM_CATEGORY];
            unset($aOptionalParameters[TdbShopArticle::CMS_LINKABLE_OBJECT_PARAM_CATEGORY]);
        }
        if (is_array($aOptionalParameters) && 0 === count($aOptionalParameters)) {
            $aOptionalParameters = null;
        }

        $aKey = array(
            'class' => __CLASS__,
            'method' => 'GetDetailLink',
            'bIncludePortalLink' => $bAbsolute,
            TdbShopArticle::CMS_LINKABLE_OBJECT_PARAM_CATEGORY => $sCategoryId,
            'id' => $this->id,
            'table' => $this->table,
        );
        if (is_null($sCategoryId)) {
            $oActiveCategory = $shopService->getActiveCategory();
            if ($oActiveCategory) {
                $aKey[TdbShopArticle::CMS_LINKABLE_OBJECT_PARAM_CATEGORY] = $oActiveCategory->id;
            }
        }
        $sKey = TCacheManager::GetKey($aKey);
        $sLink = $this->GetFromInternalCache('link'.$sKey);
        if (is_null($sLink)) {
            if (!array_key_exists('product_url_mode', $oShop->sqlData)) {
                $oShop->sqlData['product_url_mode'] = 'V1';
            }
            switch ($oShop->sqlData['product_url_mode']) {
                case 'V2':
                    $sLink = $this->GetDetailLinkV2($bAbsolute, $sCategoryId, $portal, $language);
                    break;
                case 'V1':
                default:
                    $sLink = $this->GetDetailLinkV1($bAbsolute, $sCategoryId);
                    break;
            }
            $this->SetInternalCache('link'.$sKey, $sLink);
        }
        if (null !== $aOptionalParameters) {
            $sLink .= $this->getUrlUtil()->getArrayAsUrl($aOptionalParameters, '?', '&');
        }

        if (null !== $sAnchor) {
            $sLink .= '#'.urlencode($sAnchor);
        }

        return $sLink;
    }