/**
     * @return bool
     */
    public function htmlBuildResult()
    {
        parent::htmlBuildResult();

        $applicationIds = CountryApplicationLibrary::fetchAuthorizedApplicationIds();

        foreach( $applicationIds as $k => $v )
        {
            if(!$v)
                unset($applicationIds[$k]);
        }

        $applicationIds                  = array_values($applicationIds);
        $applications                    = ApplicationLocalized::fetchApplicationList( array('id' => array($applicationIds)) );
        $applicationWebtrendsIdentifiers = array();

        foreach( $applications as $k => $app )
        {
            /* @var $app ApplicationObject */
            $applicationWebtrendsParams = $app->applicationLocalized()->webtrendsParams();

            if( trim($applicationWebtrendsParams['cg_n']) != '' )
                $applicationWebtrendsIdentifiers[strval($app->attribute('id'))] = $applicationWebtrendsParams['cg_n'];
        }

        $this->tpl()->setVariable( 'apps_wb_labels', $applicationWebtrendsIdentifiers );

        /* @var $app ApplicationLocalized */
        foreach( CacheApplicationTool::clusterApplications() as $app )
        {
            if( $app->applicationObject->identifier == 'merck-connect' )
            {
                $this->tpl()->setVariable( 'merck_connect_results', true );
                break;
            }
        }

        return true;
    }
 /**
  * @return int[]
  */
 protected function applicationIds()
 {
     return CountryApplicationLibrary::fetchAuthorizedApplicationIds();
 }
    /**
     * @param bool $forAnonmyous
     * @param null $processedUserCustomerType
     * @return int[]
     */
    public static function fetchAuthorizedApplicationIds( $forAnonmyous = false, $processedUserCustomerType = null )
    {
        if( !$forAnonmyous && !is_null(self::$_authorizedApplications) )
            return self::$_authorizedApplications;
        $db = MMDB::instance();

        $customerType   = null;
        $mainSpeciality = null;

        $whereString = sprintf(
            "     cluster_identifier='%s' 
              AND environment & %d",
            $db->escapeString(ClusterTool::clusterIdentifier()),
            ContextTool::instance()->environment()
        );
        
        $user = $forAnonmyous ? false : MMUsers::getCurrentUserObject();

        if( $user )
        {
            /* @var $user MMUsers */
            $user = MMUsers::getCurrentUserObject();

            $customerType   = $user->attribute('customer_type');
            $mainSpeciality = $user->attribute('main_speciality');

            if( $user->hasAttribute('prefered_language'))
            {
                $language = $user->attribute('prefered_language');

                $whereString.= sprintf(
                    " AND ( language = '%s' OR language IS NULL OR language = '0' )",
                    $db->escapeString($language)
                );
            }

            if( $user->hasAttribute('country'))
            {
                $country = $user->attribute('country');

                $whereString.= sprintf(
                    " AND ( country = '%s' OR country IS NULL OR country = '0' )",
                    $db->escapeString($country)
                );
            }
        }

        if (!$customerType && $processedUserCustomerType) {
            $customerType = $processedUserCustomerType;
        }
        $whereString .= is_null($customerType)
            ? ' AND customer_type IS NULL '
            : sprintf( " AND ( customer_type IS NULL OR customer_type = '0' OR customer_type='%s') ", $db->escapeString($customerType) );
        $whereString .= is_null($mainSpeciality)
            ? ' AND main_speciality IS NULL '
            : sprintf( " AND ( main_speciality IS NULL OR main_speciality = '0' OR main_speciality='%s') ", $db->escapeString($mainSpeciality) );

        $sql = "SELECT *
            FROM mm_country_application_library
            WHERE
            ".$whereString."
            ORDER BY country DESC, language DESC, customer_type DESC, main_speciality DESC";

        $lastProfile    = null;
        $excludedApps   = array();
        $applicationIds = array();

        foreach( $db->arrayQuery($sql) as $row )
        {
            $profile = serialize( array($row['customer_type'], $row['main_speciality']) );
            if( !is_null($lastProfile) && $profile != $lastProfile )
                break;

            $lastProfile = $profile;

            if( $user && $user->hasAttribute('state') && !is_null($user->attribute('state')) && $row['state'] === $user->attribute('state') )
            {
                $excludedApps[] = (int)$row['application_id'];
                continue;
            }

            $applicationIds[] = (int) $row['application_id'];
        }

        if( !empty($excludedApps) )
        {
            foreach ( $applicationIds as $k => $appId )
            {
                if( in_array($appId, $excludedApps ) )
                    unset( $applicationIds[$k] );
            }
            $applicationIds = array_values($applicationIds);
        }
        
        if(SolrSafeOperatorHelper::featureIsActive('LearningNeedsAssessment'))
        {
            $applicationIds[] = ApplicationObject::fetchByIdentifier('learning-needs-assessment')->attribute('id');
        }

        $applicationIds = array_unique( $applicationIds );

        if( !$forAnonmyous )
            self::$_authorizedApplications = $applicationIds;

        return $applicationIds;
    }
    /**
     * @return array
     */
    public static function getApplicationLists()
    {
        $userAppList = AppBarControl::instance()->applicationIds();
        $orderedAppList = $userAppList;
        $apps = array();

        sort($orderedAppList);

        $rawApps = ApplicationLocalized::fetchApplicationList(array('id' => array($orderedAppList)));

        foreach ( $rawApps as $k => $app )
        {
            $force = false;
            if(SolrSafeOperatorHelper::featureIsActive('LearningNeedsAssessment') && $app->identifier == 'learning-needs-assessment')
            {
                $force = true;
            }

            if ( $app->attribute('application_library') || $force )
            {
                /* @var $app ApplicationLocalized */
                $apps['#' . $app->attribute('id')] = $app;
            }
            else
            {
                unset($userAppList[array_search($app->attribute('id'), $userAppList)]);
                $userAppList = array_values($userAppList);

                unset($orderedAppList[array_search($app->attribute('id'), $orderedAppList)]);
                $orderedAppList = array_values($orderedAppList);
            }
        }

        // we check if some apps were deleted in the meantime
        if ( self::user() )
        {
            $applistToUpdate = false;

            foreach ( $userAppList as $k => $id )
            {
                if ( !isset($apps['#' . $id]) )
                {
                    // we remove the application from the app bar only if it is not available for the anonymous
                    // display rights are handled at application level
                    if ( !in_array($id, CountryApplicationLibrary::fetchAuthorizedApplicationIds(true)) )
                    {
                        unset($userAppList[$k]);
                        $applistToUpdate = true;
                    }
                    else
                    {
                        $apps['#' . $id] = CacheApplicationTool::buildLocalizedApplicationByApplication($id);
                    }
                }
            }
            if ( $applistToUpdate )
            {
                $userAppList = array_values($userAppList);
                $user = MMUsers::getCurrentUserObject();
                $orderedAppList = $userAppList;

                sort($orderedAppList);

                $user->setApplicationList($userAppList);
            }
        }

        return array(
            'app_list' => self::user() ? $orderedAppList : $userAppList,
            'apps'     => $apps
        );
    }
    /**
     * @param int[] $applicationIds
     * @return int[]
     */
    public function store($applicationIds = null)
    {
        $oldApplicationIds = false;
        if($this->user())
        {
            $oldApplicationIds = $this->user()->getApplicationList();
        }

        if( is_array($applicationIds) )
        {
            $this->_applicationIds = $applicationIds;
        }

        if ( !$this->user() )
        {
            CookieTool::destroyCookie(self::COOKIE_UNORDERED_APPLIST_KEY);
            return null;
        }

        $applicationIds = $this->applicationIds();
        $this->user()->setApplicationList($applicationIds);
        $this->user()->setCookie();

        sort($applicationIds);

        CookieTool::setCookie( self::COOKIE_UNORDERED_APPLIST_KEY, $applicationIds );

        if($oldApplicationIds)
        {
            $diff = array_values(array_diff($oldApplicationIds, $this->_applicationIds));

            if(is_array($diff) && count($diff) > 1)
            {
                return $diff;
            }

            else if(count($diff) == 1)
            {
                $idDeleted  = $diff[0];
                $apps       = CountryApplicationLibrary::fetchAuthorizedApplicationIds();

                if( !in_array($idDeleted, $apps) )
                {
                    return false;
                }

                return $diff;
            }
        }
        return false;
    }
    /**
     * @return array
     */
    public static function version_json()
    {
        $cacheManifest = CacheTool::dailyValue(self::MOBILE_MANIFEST_NAME);

        if(is_null($cacheManifest))
            $cacheManifest = array();

        $allAppIds = CountryApplicationLibrary::fetchAuthorizedApplicationIds();
        $applicationIds = array('my-selection', 'application-library', 'register', 'global-search', 'contactus-fr', 'sendtocolleague', 'mobile-app-settings');

        foreach ( $allAppIds as $appId )
        {
            if ( $appId == 0 )
                continue;

            $applicationLocalized = CacheApplicationTool::buildLocalizedApplicationByApplication($appId);

            if ( !($applicationLocalized instanceof ApplicationLocalized) )
                continue;

            if ( (bool) $applicationLocalized->applicationObject->attribute('application_library') )
            {

                $applicationIds[] = $applicationLocalized->applicationObject->attribute('identifier');
            }
        }

        $newApps = array_diff($applicationIds, array_keys($cacheManifest));
        if(count($newApps))
        {
            // fill the cacheManifest with new entry
            foreach($newApps as $newApp)
            {
                $cacheManifest[$newApp] = array("js" => array_flip(self::getJavascript($newApp, 'all')),
                                                "css" => array_flip(self::getCSS($newApp))
                                               );
            }
            // save new applications in cache
            CacheTool::dailyValue(self::MOBILE_MANIFEST_NAME, $cacheManifest);
        }

        $js     = array();
        $css    = array();
        foreach($applicationIds as $id)
        {
            $js     = array_merge($js, $cacheManifest[$id]["js"]);
            $css    = array_merge($css, $cacheManifest[$id]["css"]);
        }

        return array_unique(array_merge($js, $css));
    }
    /**
     * @return bool
     */
    public function canRead()
    {
        if( !$this->isFull || !$this->user() )
            return true;

        if( $this->isFull )
            return ( in_array( $this->_applicationFull->attribute('id'), CountryApplicationLibrary::fetchAuthorizedApplicationIds() ) );
    }
    /**
     * @param int $parent
     * @param int $id
     * @return ApplicationObject
     */
    public static function fetchByParent($parent, $id = null)
    {
        $cond = array('parent_id' => $parent);
        $isLoggedUser = MMUsers::getCurrentUserObject();

        if( !$isLoggedUser )
        {
            $restricted = array(
                'restriction_level' => array(
                    array(
                            self::RESTRICTION_LEVEL_PUBLIC,
                            self::RESTRICTION_LEVEL_RESTRICTED
                    )
                )
            );
        }
        else
        {
            $restricted = array(
                'id' => array(
                    CountryApplicationLibrary::fetchAuthorizedApplicationIds()
                )
            );
        }

        $cond        = array_merge($cond, $restricted);
        $relatedApps = ApplicationLocalized::fetchApplicationList ( $cond );

        if( $id )
        {
            for( $i=0; $i<count($relatedApps); $i++ )
            {
                if( $relatedApps[$i]->id == $id )
                {
                    unset($relatedApps[$i]);
                    break;
                }
            }
        }

        $wantedChildApps = array();
        $i = 0;
        foreach ($relatedApps as $relatedApp)
        {
            $passAppToView = true;
            $appLocalized = $relatedApp->applicationLocalized();
            if ( $appLocalized instanceof ApplicationLocalized && !$isLoggedUser)
            {
                if ( !in_array( $appLocalized->restrictionLevel(), $restricted['restriction_level'][0] ) )
                {
                    $passAppToView = false;
                }
            }

            if ( $passAppToView )
            {
                $wantedChildApps[$i] = $relatedApp;
                $i++;
            }
        }

        return $wantedChildApps;
    }
    /**
     * @override
     * @return boolean
     */
    public function canRead()
    {
        if ( $this->applicationObject() )
        {
            $applicationIdentifier = $this->getApplicationIdentifier();
            $restrictionLevel = $this->applicationLocalized()->restrictionLevel();

            if( $restrictionLevel == ApplicationObject::RESTRICTION_LEVEL_PUBLIC )
            {
                return true;
            }
            else
            {
                if( !(bool)self::user()   // if anonymous
                    ||                    // or if ToU not validated
                    (      (bool)self::user()
                        && !self::user()->toUValidated()
                        && $this->iniMerck()->hasVariable( 'LoginSettings', 'ToUCheck' )
                        && $this->iniMerck()->variable( 'LoginSettings', 'ToUCheck') != 'disabled'
                     )
                     ||                   // or if autologin and app set to be restricted
                     (      (bool)self::user()
                        && self::user()->isAutologin()
                        && SolrSafeOperatorHelper::featureIsActive('RestrictAutologgedInUsers')
                        && SolrSafeOperatorHelper::feature('RestrictAutologgedInUsers', 'Restricted')
                        &&
                        (
                            (
                                $applicationIdentifier == 'my-account'
                                && SolrSafeOperatorHelper::feature('RestrictAutologgedInUsers', 'SecureMyProfile')
                            )
                            ||
                            (
                                $this->applicationLocalized()
                                && $this->applicationLocalized()->getCustomParameter( 'RestrictAutologgedInUsers' )
                            )
                        )
                     )
                ){
                    return ( $restrictionLevel == ApplicationObject::RESTRICTION_LEVEL_PUBLIC );
                }
                else
                {
                    return in_array( $this->getApplicationId(), CountryApplicationLibrary::fetchAuthorizedApplicationIds() );
                }
            }
        }
        else
        {
            return false;
        }
    }
    /**
     * @param string $customerType
     * @param string $mainSpeciality
     * @param string $country
     * @return int[]
     */
    public static function fetchAppsBarApplicationIds( $customerType = null, $mainSpeciality = null,  $country = null )
    {
        $profileKey = md5($customerType.$mainSpeciality.$country);

        if( !isset( self::$_appsBarApplicationIds[$profileKey]) )
        {
            $state          = null;
            $userApps       = null;

            $db = MMDB::instance();

            $whereString = sprintf(
                " cluster_identifier='%s'",
                $db->escapeString(ClusterTool::clusterIdentifier())
            );

            // user specific
            if( MMUsers::getCurrentUserObject() )
            {
                /* @var $user MMUsers */
                $user = MMUsers::getCurrentUserObject();

                if( $user->getApplicationList() )
                {
                    $userApps = $user->getApplicationList();
                }

                // @TODO: implement state and prefered language in JSP and in MMUser
                $country        = $user->attribute( 'country' );
                $customerType   = $user->attribute( 'customer_type' );
                $mainSpeciality = $user->attribute( 'main_speciality' );

                if ( $user->hasAttribute( 'prefered_language' ) )
                {
                    $language = $user->attribute( 'prefered_language' );

                    $whereString .= sprintf(
                        " AND ( language = '%s' OR language IS NULL )",
                        $db->escapeString($language)
                    );
                }

                if ( $user->hasAttribute( 'state' ) )
                {
                    $state = $user->attribute( 'state' );
                }


            }

            if ( $country )
            {
                $whereString .= sprintf( " AND ( country = '%s' OR country IS NULL )", $db->escapeString($country) );
            }
            else
            {
                $whereString .= ' AND country IS NULL ';
            }
            if ( $customerType )
            {
                $whereString .= sprintf( " AND ( customer_type IS NULL OR customer_type = '0' OR customer_type = '%s' ) ", $db->escapeString( $customerType ) );
            }
            else
            {
                $whereString .= ' AND customer_type IS NULL ';
            }

            if ( $mainSpeciality )
            {
                $whereString .= sprintf( " AND ( main_speciality IS NULL OR main_speciality = '%s' ) ", $db->escapeString( $mainSpeciality ) );
            }
            else
            {
                $whereString .= ' AND main_speciality IS NULL ';
            }

            $sql = 'SELECT application_id, state, `order` FROM mm_country_apps_bar WHERE '.$whereString.' ORDER BY country DESC, language DESC, customer_type DESC, main_speciality DESC, `order` ASC';

            $applicationIds = array();
            $lastOrder      = 0;
            $forbiddenApps  = array();

            foreach( $db->arrayQuery($sql) as $row )
            {
                if( $row['order'] <= $lastOrder )
                {
                    break;
                }

                $lastOrder = $row['order'];

                if( $state && $row['state'] == $state )
                {
                    // forbidden app for user
                    $forbiddenApps[] = (int)$row['application_id'];
                    continue;
                }

                $applicationIds[] = (int)$row['application_id'];
            }

            if( $userApps )
            {
                $applicationIds = array_intersect( $userApps, CountryApplicationLibrary::fetchAuthorizedApplicationIds(false) );
            }
            else
            {
                $applicationIds = array_intersect( $applicationIds, CountryApplicationLibrary::fetchAuthorizedApplicationIds(true, $customerType) );
            }
            
            if( !empty($forbiddenApps) )
            {
                $applicationIds = array_diff( $applicationIds, $forbiddenApps );
            }

            self::$_appsBarApplicationIds[$profileKey] = array_values( $applicationIds );
        }

        return self::$_appsBarApplicationIds[$profileKey];
    }