/**
     * @see eZContentObjectEditHandler::publish()
     * @param int $contentObjectID
     * @param eZContentObjectVersion $contentObjectVersion
     */
    function publish( $contentObjectID, $contentObjectVersion )
    {
        $contentObject = eZContentObject::fetch( $contentObjectID );

        if( $contentObject instanceof eZContentObject )
        {
            switch($contentObject->ClassIdentifier)
            {
                case 'article':
                {
                    ObjectVisibilityManager::updateGlobalLimitation($contentObject);

                    /* @type $mainNode eZContentObjectTreeNode */
                    /* @type $clustersToHide array */
                    $db                 = eZDB::instance();
                    $mainNode           = $contentObject->mainNode();
                    $clustersToHide     = eZINI::instance( 'merck.ini' )->variable( 'PublishSettings', 'clustersToHide' );
                    $publisherNodeId    = PublisherFolderTool::getPublisherNodeIdFromArticleNode($mainNode);
                    $publisherInfo      = PublisherFolderTool::getNodeIdToPathMapping($publisherNodeId);
                    $publisherClusters  = PublisherFolderTool::getClustersFromPath($publisherInfo['path']);
                    $inserted           = false;
                    
                    foreach( $clustersToHide as $clusterToHide )
                    {
                        if( in_array($clusterToHide, $publisherClusters) )
                        {
                            if ( !$inserted )
                            {
                                $db->query( sprintf(
                                    "INSERT INTO ezpending_actions (action, created, param)
                                        VALUES ('check_node_visibility', %d, '%s' )",
                                    time(),
                                    $contentObject->mainNodeID()
                                ));
                                $inserted = true;
                            }
                            
                            ObjectVisibilityManager::updateClusterLimitation($contentObjectID, $clusterToHide, true);
                        }
                    }
                }
                break;
            }
        }
    }
/**
 * @param array $contentObjectList
 */
function checkObjectVisibility ($contentObjectList)
{
    foreach ( array_keys($contentObjectList) as $index )
    {
        $contentObjectId  = $contentObjectList[$index]['contentobject_id'];

        echo "Checking visibility of object $contentObjectId\n";

        $articleContentObject = eZContentObject::fetch($contentObjectId);

        if ( $articleContentObject && $articleContentObject->attribute('class_identifier') === "article" )
            ObjectVisibilityManager::updateGlobalLimitation($articleContentObject);

        unset($articleContentObject);

        eZContentObject::clearCache();
    }
}
    /**
     * @param int $contentObjectId
     * @return boolean[]
     */
    public static function getClusterVisibilities($contentObjectId)
    {
        $clusters = ClusterTool::globCluster();
        $visibilities = array();

        foreach( $clusters as $cluster )
        {
            $visibilities[$cluster] = !ObjectVisibilityManager::isClusterLimited( $contentObjectId, $cluster );
        }

        return $visibilities;
    }
    /**
     * @param MMSelections[] $userSelection
     * @param int $offset
     * @return array
     */
    public function manageResults( $userSelection, $offset = 0 )
    {
        $limit  = $this->applicationObject->configurationContentService->attribute('nb_of_articles_per_page');
        $facets = array('applications' => null);
        $db     = eZDB::instance();
        $query  = "select id from ezcontentobject where remote_id = '%s'";
        $isRemoved = false;

        /** @var MMSelections $selection */
        foreach( $userSelection as $key => $selection )
        {
            $result = $db->arrayQuery(sprintf(
                $query,
                $selection->attribute("remote_id")
            ));

            if ( count($result) == 1 )
            {
                $objectId = $result[0]['id'];
                $isVisible = ObjectVisibilityManager::isVisible($objectId);

                if (!$isVisible)
                {
                    unset($userSelection[$key]);
                    $selection->remove();
                    $isRemoved = true;
                    continue;
                }
            }

            $applicationIdentifier = $selection->attribute('application');
            if( $applicationIdentifier != null )
            {
                if( (CacheApplicationTool::buildLocalizedApplicationByIdentifier( $applicationIdentifier ) instanceof ApplicationLocalized) ) {
                    if( !isset( $facets['applications'][$applicationIdentifier] ) )
                        $facets['applications'][$applicationIdentifier] = 1;
                    else
                        $facets['applications'][$applicationIdentifier]++;
                } else {
                    unset($userSelection[$key]);
                    $selection->remove();
                    $isRemoved = true;
                }
            }
        }
        if ( $isRemoved ) {
            MMSelections::setCookie();
        }

        $total = count( $userSelection );

        if( $offset != 0 )
            $userSelection = array_slice( $userSelection, $offset );

        uksort( $facets['applications'], function($a, $b){
            return strnatcasecmp( ezpI18n::tr('merck/application', $a), ezpI18n::tr('merck/application', $b) );
        });

        if( $total > $limit )
            $userSelection = array_slice( $userSelection, 0, $limit );

        return array( 'items' => $userSelection, 'total' => $total, 'facets' => $facets );
    }
    /**
     * Brightcove - update article visibility on media change
     * Called from Listener factory
     */
    static function bcCheckArticlesRelatedToMedia()
    {
        $args = func_get_args();

        if( empty($args[0]) || !isset( $args[0]['id'] ) )
            return;

        $id                 = $args[0]['id'];
        $eZBrightcoveObject = eZBrightcoveObject::fetch( array( 'id' => $id ) );

        if( !($eZBrightcoveObject instanceof eZBrightcoveObject) )
            return;
                
        $mediaContentObjectId = $eZBrightcoveObject->attribute('contentobject_id');

        if( empty( $mediaContentObjectId ) )
            return;
        

        $mediaContentObject = eZContentObject::fetch( $mediaContentObjectId );

        //Get related articles
        if( $mediaContentObject->reverseRelatedObjectCount( false, 0, array('AllRelations' => true ) ) == 0 )
            return;

        $relatedArticleContentObjects = $mediaContentObject->reverseRelatedObjectList( false, 0, false, array('AllRelations' => true ) );
        $relatedArticleContentObjects = array_merge($relatedArticleContentObjects, self::getRelatedCoreContentArticle($mediaContentObjectId));

        foreach( $relatedArticleContentObjects as $relatedArticleContentObject )
        {
            if( $relatedArticleContentObject instanceof eZContentObject )
                ObjectVisibilityManager::updateGlobalLimitation($relatedArticleContentObject);
        }
    }
    /**
     * @param array $accreditationList
     * @param int $offset
     *
     * @return array Sorted and filtered list of certificates.
     */
    public function manageResults( $accreditationList = null, $offset = 0 )
    {
        $wsResults = CertificatesWebservice::getCertificatesList();
        $facets = array(
            self::$noAccreditationKeyword => 0
        );

        foreach ( $wsResults as $k => $result )
        {
            $fetchResult = self::fetchNodeAndAppFromCourseId( $result['CourseID'] );

            if ( $result['CompletionDateTime'] != '' )
            {
                $tempDate = DateTime::createFromFormat( $this->dateFormat, $result['CompletionDateTime'] );
                if ( $tempDate instanceof DateTime )
                {
                    $wsResults[$k]['CompletionDateTime'] = $tempDate->getTimestamp();
                }
                else
                {
                    $wsResults[$k]['CompletionDateTime'] = '';
                }
            }

            if ( $fetchResult === false || (isset($fetchResult['node']) && !ObjectVisibilityManager::isVisible($fetchResult['node']->ContentObjectID)) )
            {
                $wsResults[$k]['SimpleView'] = true;
                $facets[self::$noAccreditationKeyword] += 1;
                if ( !self::isAccreditationSourceChosen( self::$noAccreditationKeyword, $accreditationList ) )
                {
                    unset( $wsResults[$k] );
                }
                continue;
            }
            /* @type $node eZContentObjectTreeNode */
            /* @type $dm eZContentObjectAttribute[] */
            $node           = $fetchResult['node'];
            $wsResults[$k]  = array_merge($wsResults[$k], $fetchResult);
            $dm             = $node->dataMap();
            $tags = array();
            if ( $dm['serialized_taxonomies'] instanceof eZContentObjectAttribute )
            {
                $serializedTaxonomies = $dm['serialized_taxonomies']->content();
                if ( isset( $serializedTaxonomies['accreditation_source'] ) )
                {
                    $tags = (array) $serializedTaxonomies['accreditation_source'];
                }
            }

            if ( count( $tags ) == 0 )
            {
                $wsResults[$k]['SimpleView'] = true;
                $facets[self::$noAccreditationKeyword] += 1;
                if ( !self::isAccreditationSourceChosen( self::$noAccreditationKeyword, $accreditationList ) )
                {
                    unset( $wsResults[$k] );
                }
                continue;
            }

            foreach ( $tags as $keyword )
            {
                if ( !isset( $facets[$keyword] ) )
                {
                    $facets[$keyword] = 0;
                }

                $facets[$keyword] += 1;

                if ( !self::isAccreditationSourceChosen( $keyword, $accreditationList ) )
                {
                    unset( $wsResults[$k] );
                }
            }
        }
        $articleTotal = count( $wsResults );

        return array(
            "items" => self::sortAndPaginate( $wsResults, $articleTotal, $offset ),
            "facets" => array(
                "accreditation_source" => $facets
            ),
            "total" => $articleTotal,
        );
    }
                                if( $dates['daysLeft'] > 0 )
                                {
                                    $articleObject = $article->object();
                                    $relatedArticles[] = $articleObject;
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach( $relatedObjects as $relatedObject )
                        {
                            /* @var $relatedObject eZContentObject */
                            if( $relatedObject->ClassIdentifier == 'article' )
                            {
                                $isVisible = ObjectVisibilityManager::isVisible($relatedObject->attribute('id'));

                                if( $isVisible )
                                {
                                    /* @type $articleDatamap eZContentObjectAttribute[] */
                                    $articleDatamap = $relatedObject->dataMap();

                                    if( isset($articleDatamap['online_date'])
                                        && $articleDatamap['online_date']->hasContent() )
                                    {
                                        /* @type $onlineDateContent eZDate */
                                        $onlineDateContent = $articleDatamap['online_date']->content();
                                        $onlineDate        = $onlineDateContent->timestamp();
                                        $dates             = SolrSafeOperatorHelper::getDatesPDFavailable($onlineDate,$expirationDuration);

                                        if( $dates['daysLeft'] > 0 )
    /**
     * 
     * @param string $nodePath
     * @param ApplicationDefault $app
     * @return null
     */
    static public function findNodeFromPath ($nodePath, $app )
    {
        $uri             = explode( '/', ltrim( $nodePath, '/' ) );
        $rootNodes       = array();
        $applicationName = $app->applicationName();

        if( count( $uri ) > 1 && is_numeric($uri[0]) )
        {
            $publisherFolderId = $uri[0];
            array_shift($uri);
            $uriArticle = implode ('/', $uri);
        }
        else
            $uriArticle = ltrim( $nodePath, '/' );
        
        $uriArticle = urldecode($uriArticle);

        if($applicationName)
        {
            $publishers = $app->applicationLocalized()->publisherFolders;

            /* @var $publisher PublisherFolder */
            foreach ($publishers as $publisher)
            {
                $pfids = PublisherFolderTool::getPathToIDMapping( $publisher->attribute('path') );

                // If PublisherFolderId is included in url, we only take care about this publisher folder
                if ( isset($publisherFolderId) && $pfids['pfid'] == $publisherFolderId )
                {
                    $rootNodes[] = eZContentObjectTreeNode::fetch($pfids['nid']);
                    $articlePath = $uriArticle;

                    break;
                }
                elseif( !isset($publisherFolderId) )
                {
                    $node = eZContentObjectTreeNode::fetch($pfids['nid']);
                    if($node) {
                        $rootNodes[] = $node;
                        $articlePath = $uriArticle;
                    }
                }
            }
        }

        if ( isset($publisherFolderId) != false && trim($uriArticle) == '' )
            return $app;
        
        if ( !isset($articlePath) || count($rootNodes) == 0 )
            return null;

        $node = self::getNodeFromPath ($articlePath, $rootNodes);

        if ( !$node )
            return null;
        
        $cluster   = $app->applicationLocalized()->attribute( 'cluster_identifier' );
        $isVisible = ObjectVisibilityManager::isVisible( $node->attribute('contentobject_id'), $cluster );

        if ( !$isVisible )
            return null;

        return $node;
    }
    /**
     * @param array $row
     */
    public static function updateNodeVisibility($row)
    {
        /* @type $node eZContentObjectTreeNode */
        $comment      = "";
        $db           = eZDB::instance();
        $pendingBased = !isset($row['manual']);
        $nodeId       = (int)$row['param'];
        $delete       = true;
        $nodeFetch    = eZContentObjectTreeNode::fetch( $nodeId );

        if ( !($nodeFetch instanceof eZContentObjectTreeNode) )
            $comment = "Not found in eZ Publish";
        else
        {
            $node = $nodeFetch->findMainNode($nodeFetch->attribute('contentobject_id'), true);

            if ($node)
            {
                if ($node->object()->ClassIdentifier == 'article')
                {
                    $toHideResults = self::nodeHasForbiddenWords($node, $row);

                    foreach ($toHideResults as $cluster => $toHideResult)
                    {
                        if ($toHideResult['toHide'])
                        {
                            ObjectVisibilityManager::updateClusterLimitation(
                                $node->attribute('contentobject_id'),
                                $cluster,
                                true
                            );
                        }
                        else
                        {
                            $parentIsInvisible = false;

                            if ($node->attribute('depth') > 4)
                            {
                                $parentNode        = $node->fetchParent();
                                $parentIsInvisible = ObjectVisibilityManager::isClusterLimited(
                                    $parentNode->attribute('contentobject_id'),
                                    $cluster
                                );
                            }

                            if ($parentIsInvisible)
                            {
                                ObjectVisibilityManager::updateClusterLimitation(
                                    $node->attribute('contentobject_id'),
                                    $cluster,
                                    false
                                );
                            }
                            else
                            {
                                ObjectVisibilityManager::removeClusterLimitation(
                                    $node->attribute('contentobject_id'),
                                    $cluster
                                );
                            }
                        }

                        if (!$toHideResult['toDelete'])
                        {
                            $delete = false;
                        }

                        $comment .= sprintf(";Cluster : %s - Message : %s", $cluster, $toHideResult['comment']);
                    }
                }
            }
            else
            {   // node does not exist in ez - we delete the pending row
                $comment = "Not found in eZ Publish";
            }
        }

        if( $delete && $pendingBased )
            $db->query( sprintf( "DELETE FROM ezpending_actions WHERE id = %d", $row['id'] ) );

        eZLog::write( "RowId : {$row['id']}; Node : $nodeId $comment", 'updatevisibility.log' );

        unset( $node );
        eZContentObject::clearCache();
    }
        if ( $i%100 == 0 )
            $cli->notice( "$i nodes have been treated." );

        $i++;

        if ( !isset($result) || !isset($result['contentobject_id']) )
        {
            $cli->warning("We somehow got an invalid MySQL entry");
            continue;
        }

        $contentObjectId = $result['contentobject_id'];
        $contentObject   = eZContentObject::fetch($contentObjectId);

        if ( $contentObject instanceof eZContentObject )
            ObjectVisibilityManager::updateGlobalLimitation ( $contentObject );
        else
        {
            $cli->warning("$contentObjectId is not a valid object.");
            continue;
        }

        unset($contentObject);
        eZContentObject::clearCache();
    }

    $offset+= $limit;
}

$cli->notice( "Treatment completed successfully; $i nodes treated." );
    /**
     * The modify method gets the current content object AND the list of
     * Solr Docs (for each available language version).
     *
     * @param eZContentObject $contentObject
     * @param eZSolrDoc[] $docList
     */
    public function modify( eZContentObject $contentObject, &$docList )
    {
        /* @var eZContentObjectTreeNode $contentMainNode */
        $contentMainNode        = $contentObject->mainNode();
        $contentObjectLanguages = $contentObject->allLanguages();
        $articleLanguageArray   = array_keys($contentObjectLanguages);
        $publisherFolderNodeId  = PublisherFolderTool::getPublisherNodeIdFromArticleNode($contentMainNode);
        $isMerckManualShowcase  = false;
        // Depth : 0 => father article, 1+ => child article
        $articleRelativeDepth   = $contentMainNode->attribute('depth') - 4;

        if ( is_null($publisherFolderNodeId) )
            return;

        $publisherFolderInfos = PublisherFolderTool::getPublisherFolderInfosFromNodeId($publisherFolderNodeId);
        
        if ( !$publisherFolderInfos )
            return;

        $publisherFolderRelations = PublisherFolderTool::getPublisherFolderRelations($publisherFolderInfos['path']);

        if ( !$publisherFolderRelations || count($publisherFolderRelations['clusters']) === 0 )
            return;

        // node remote
        $remote = $contentMainNode->attribute("remote_id");
        $this->addValueToDoc( $docList, 'attr_node_remote_s', $remote);
        $this->addValueToDoc( $docList, 'attr_relative_depth_i', $articleRelativeDepth);

        foreach ( $publisherFolderRelations['clusters'] as $cluster => $applications )
        {
            ClusterTool::setCurrentCluster( $cluster );
            
            $applicationIdentifier = $applications[0];

            /* @var $applicationLocalized ApplicationLocalized */
            $applicationLocalized = CacheApplicationTool::buildLocalizedApplicationByIdentifier( $applicationIdentifier );

            if ( !($applicationLocalized instanceof ApplicationLocalized) )
            {
                if (count($applications) == 1)
                {
                    unset($publisherFolderRelations['clusters'][$cluster]);
                    continue;
                }

                $applicationIdentifier = $applications[1];
                $applicationLocalized = CacheApplicationTool::buildLocalizedApplicationByIdentifier( $applicationIdentifier );

                if ( !($applicationLocalized instanceof ApplicationLocalized) )
                {
                    unset($publisherFolderRelations['clusters'][$cluster]);
                    continue;
                }
                
                $publisherFolderRelations['clusters'][$cluster] = array ($applicationIdentifier);
            }

            // visibility per cluster
            $isVisible = ObjectVisibilityManager::isVisible($contentMainNode->attribute('contentobject_id'), $cluster);

            $this->addValueToDoc( $docList, 'attr_is_invisible_' . $cluster . '_b', !$isVisible );

            if (!isset(self::$_applicationIdentifierToId[$applicationIdentifier]))
                self::$_applicationIdentifierToId[$applicationIdentifier] = $applicationLocalized->applicationObject()->attribute ('id');

            $publisherFolder              = $applicationLocalized->getPublisherFolderFromPath($publisherFolderInfos['path']);
            $publisherLanguages           = $publisherFolder->getLanguages();
            $publisherAndArticleLanguages = array_intersect($publisherLanguages, $articleLanguageArray);

            if ( count($publisherAndArticleLanguages) == 0 )
                continue;

            $primaryLanguage = reset($publisherAndArticleLanguages);
            $contentMainNode->setCurrentLanguage($primaryLanguage);

            // publisher folder languages
            $languageKey       = 'subattr_language_' . $cluster . '____s';
            $formatedLanguages = array_map(
                array('kezfSolrArticleIndex', 'languageCode') ,
                $publisherAndArticleLanguages
            );

            $indexLanguages = array_unique( $formatedLanguages );

            $this->addValueToDoc( $docList, $languageKey, $indexLanguages, true, false );
            
            // Meck manual sections
            if( $applicationIdentifier == MerckManualShowcase::mainApplicationIdentifier() )
                $isMerckManualShowcase = true;

            // url computation
            /* @var eZContentObjectAttribute[] $dataMap */
            $dataMap = $contentMainNode->dataMap();

            ClusterTool::setCurrentCluster( $cluster );

            if( $applicationIdentifier == MerckManualShowcase::mainApplicationIdentifier() )
            {
                $urlContent = preg_replace(
                    '#^([^/]+/){2}#',
                    '',
                    MerckManualFunctionCollection::getMerckManualNodeUrl(
                        $applicationIdentifier,
                        $contentMainNode,
                        $primaryLanguage
                    )
                );
            }
            else
                $urlContent = preg_replace( '#^([^/]+/){2}#', '', $contentMainNode->urlAlias() );

            $this->addValueToDoc( $docList, 'attr_' . $cluster . '_url_s', $urlContent);

            $hasImage = array();

            for ( $mediaCase = 0; $mediaCase<=2; $mediaCase++ )
            {
                $hasImage[$mediaCase] = NodeOperatorHelper::hasImageArticle($contentMainNode, $mediaCase);
            }

            self::addValueToDoc( $docList, 'attr_has_image_' . $cluster . '_bst', base64_encode(json_encode($hasImage)) );

            $db = MMDB::instance();

            // index rating
            $row = $db->arrayQuery(sprintf("SELECT * FROM mm_rating_remote WHERE cluster_identifier = '%s' AND remote_id = '%s'", $cluster, $contentObject->remoteID()));
            if(count($row) && $row[0]["counter"] > 5 )
            {
                self::addValueToDoc( $docList, 'attr_content_rating_'.$cluster.'_f', $row[0]["total"]/$row[0]["counter"] );
                //update to_reindex
                $db->query(sprintf("UPDATE mm_rating_remote SET to_reindex=0 WHERE cluster_identifier = '%s' AND remote_id = '%s'", $cluster, $contentObject->remoteID()));
            }

            // index views
            $row = $db->arrayQuery(sprintf("SELECT * FROM mm_readcount_remote WHERE cluster_identifier = '%s' AND remote_id = '%s'", $cluster, $contentObject->remoteID()));
            if(count($row) && $row[0]["count"] > 0 )
            {
                self::addValueToDoc( $docList, 'attr_view_counter_'.$cluster.'_i', $row[0]["count"] );
                //update to_reindex
                $db->query(sprintf("UPDATE mm_readcount_remote SET to_reindex=0 WHERE cluster_identifier = '%s' AND remote_id = '%s'", $cluster, $contentObject->remoteID()));
            }

            if( $dataMap && $dataMap['media_content']->hasContent() )
            {
                $mediaContent      = $dataMap['media_content']->content();
                $mediaRelationList = $mediaContent['relation_list'];
                $entries           = array();
                $firstLink         = true;
                $totalQuizzes      = 0;

                foreach ( $mediaRelationList as $mediaRelation )
                {
                    $mediaObjectId = $mediaRelation['contentobject_id'];
                    $mediaClass = $mediaRelation['contentclass_identifier'];

                    /*******************************************************************************
                     * TODO : Adapt after PF Refactor
                     *******************************************************************************/
                    if ( !in_array($mediaClass, array('image', 'quiz', 'link')) )
                        continue;

                    
                    if ( $mediaClass === 'image' )
                    {
                        if ( count( $entries ) >= 3 )
                            continue;

                        // Language is DEPRECATED, Fake Language instead
                        $entries[] = $mediaObjectId . ";dep-DP";
                        /*******************************************************************************
                         * TODO : End : Adapt after PF Refactor
                         *******************************************************************************/
                    }
                    elseif ( ( $mediaClass === 'link' && $firstLink ) || $mediaClass === 'quiz' )
                    {
                        $mediaObject = eZContentObject::fetch( $mediaObjectId );

                        if ( !$mediaObject )
                            continue;

                        /* @var eZContentObjectAttribute[] $mediaDatamap */
                        $mediaDatamap = $mediaObject->dataMap();

                        if ( !is_array($mediaDatamap) )
                            continue;

                        if ( $mediaClass === 'link' )
                        {
                            if (!$mediaDatamap['url']->hasContent())
                                continue;

                            $firstLink = false;

                            self::addValueToDoc( $docList, 'attr_media_content_link_' . $cluster . '____ms', $mediaDatamap['url']->content(), false );
                        }
                        elseif ( $mediaClass === 'quiz' )
                        {
                            if ( $mediaDatamap['replies']->hasContent() )
                            {
                                $quizReplies = $mediaDatamap['replies']->content();
                                $quizReplies = $quizReplies->attribute('columns');
                                $quizReplies = $quizReplies['sequential'][1]['rows'];

                                if ( count($quizReplies) > 0 )
                                    self::addValueToDoc( $docList, 'attr_media_content_quiz_replies_' . $cluster . '____ms', $quizReplies, true);
                            }

                            if ( !empty($mediaDatamap['question']->DataText) )
                            {
                                self::addValueToDoc( $docList, 'attr_media_content_quiz_question_' . $cluster . '_ms', trim(strip_tags($mediaDatamap['question']->DataText)), false );
                            }

                            if ( !$mediaDatamap['points']->hasContent() )
                                continue;

                            $totalQuizzes+= $mediaDatamap['points']->content();
                        }
                    }
                }

                $withMediaDuration    = true;
                $typeMedias           = NodeOperatorHelper::getPictosMedia( $contentMainNode, $withMediaDuration );
                $typeMediasSerialized = base64_encode( json_encode($typeMedias) );

                // getPictosMedia as solr field
                self::addValueToDoc( $docList, 'attr_media_content_types_' . $cluster . '_bst', $typeMediasSerialized, false );

                // getMediaCount as solr field
                $mediaCount = NodeOperatorHelper::getMediaCount($contentMainNode);
                self::addValueToDoc( $docList, 'attr_media_content_count_' . $cluster . '_i', $mediaCount, false );

                // Used only for Quizz
                if ( $totalQuizzes > 0 )
                    self::addValueToDoc( $docList, 'attr_media_content_quiz_points_' . $cluster . '_i', $totalQuizzes, false );
            }
            
            unset($isHidden);
        }

        ClusterTool::resetCurrentCluster();

        $concernedNode = $contentMainNode;
        $concernedNode->setCurrentLanguage($articleLanguageArray[0]);

        if ( $contentMainNode->attribute('depth') > 4 )
        {
            $concernedNode = $contentMainNode->fetchParent();
            $concernedNode->setCurrentLanguage($articleLanguageArray[0]);
        }

        /* @type $concernedDM eZContentObjectAttribute[] */
        $concernedDM = $concernedNode->dataMap();
        $tags        = $concernedDM['tags'];

        $MerckManualAboutSectionId = eZIni::instance('merck.ini')->variable('MerckManualAboutSettings', 'SectionSourceId');
        $taxonomiesAttribute       = $concernedDM['serialized_taxonomies'];

        if( $taxonomiesAttribute instanceof eZContentObjectAttribute && $taxonomiesAttribute->hasContent() )
        {
            $taxonomies = $taxonomiesAttribute->content();

            foreach( array_keys($publisherFolderRelations['clusters']) as $cluster )
            {
                self::addValueToDoc(
                    $docList,
                    "attr_exclude_from_search_{$cluster}_b",
                    $MerckManualAboutSectionId && in_array($MerckManualAboutSectionId, $taxonomies['section']),
                    false
                );
            }
        }

        if( $tags instanceof eZContentObjectAttribute && $tags->hasContent() )
            self::addValueToDoc( $docList, 'subattr_tags____ms', explode("|", $tags->content()) );

        if ( $isMerckManualShowcase )
            $this->processSpecificMerckManual($docList, $concernedNode, $concernedDM, $publisherFolderRelations);

        foreach ( $publisherFolderRelations['clusters'] as $cluster => $applications )
        {
            ClusterTool::setCurrentCluster( $cluster );

            foreach( $applications as $key => $applicationIdentifier )
            {
                if ( !isset(self::$_applicationIdentifierToId[$applicationIdentifier]) )
                {
                    $applicationLocalized = CacheApplicationTool::buildLocalizedApplicationByIdentifier( $applicationIdentifier );

                    if( !($applicationLocalized instanceof ApplicationLocalized) )
                    {
                        eZDebug::writeError(
                            sprintf('Cluster: %s; Identifier: %s; ObjectId: %s', $cluster, $applicationIdentifier, $contentObject->attribute('id') ),
                            'Error getting application localized' );
                        unset( $publisherFolderRelations['clusters'][$cluster][$key] );
                    }
                    else
                        self::$_applicationIdentifierToId[$applicationIdentifier] = $applicationLocalized->applicationObject()->attribute('id');
                }
            }
        }

        ClusterTool::resetCurrentCluster();
        
        $applicationIds = array();

        foreach ( $publisherFolderRelations['clusters'] as $cluster => $applications )
            foreach( $applications as $applicationIdentifier )
                $applicationIds[] = self::$_applicationIdentifierToId[$applicationIdentifier];

        $uniqueApplicationIds = array_unique($applicationIds);

        foreach( $docList as $languageCode => $doc )
        {
            $dataMap               = $contentObject->fetchDataMap(false, $languageCode);
            $headline              = $dataMap['headline']->content();
            $headlineLowerCase     = mb_strtolower( StringTool::removeAccents($headline, 'utf-8', false), 'utf-8' );
            $unaccentedFirstLetter = mb_substr($headlineLowerCase, 0, 1, 'utf-8');

            $doc->addField( 'attr_headline_first_letter_lc_s', $unaccentedFirstLetter );
            $doc->addField( 'attr_headline_lc_s', $headlineLowerCase );

            foreach( $uniqueApplicationIds as $id )
            {
                $doc->addField( 'subattr_local_application___source_id____s', $id );
            }

            foreach( $publisherFolderRelations['clusters'] as $cluster => $applications )
            {
                foreach( $applications as $applicationIdentifier )
                {
                    $doc->addField('subattr_local_application___source_mixed____s', $cluster . '##unused##' . self::$_applicationIdentifierToId[$applicationIdentifier]);
                }
            }
        }
    }