Fetch allowed subtreenotification rules based on node_id list and a
content object

@param array $nodeIDList node id list for notification event
@param eZContentObject content object to add

@return array matching subtree notification rule data
337701
static function fetchUserList( $nodeIDList, $contentObject )
    {
        if ( count( $nodeIDList ) == 0 )
        {
            $retValue = array();
            return $retValue;
        }

        $db = eZDB::instance();
        $concatString = $db->concatString(  array( 'user_tree.path_string', "'%'" ) );

        // Select affected users
        $sqlINString = $db->generateSQLINStatement( $nodeIDList, 'subtree_rule.node_id', false, false, 'int' );
        $sql = "SELECT DISTINCT subtree_rule.user_id,
                                user_node.node_id
                FROM ezsubtree_notification_rule subtree_rule,
                     ezcontentobject_tree user_node,
                     ezuser_setting
                WHERE $sqlINString AND
                      user_node.contentobject_id = subtree_rule.user_id AND
                      ezuser_setting.user_id = subtree_rule.user_id AND
                      user_node.is_invisible = 0 AND
                      ezuser_setting.is_enabled = 1";
        $userPart = $db->arrayQuery( $sql );

        // Remove duplicates
        $userNodeIDList = array();
        foreach ( $userPart as $row )
            $userNodeIDList[] = $row['node_id'];
        $userNodeIDList = array_unique( $userNodeIDList );

        if ( count( $userNodeIDList ) == 0 )
        {
            $retValue = array();
            return $retValue;
        }

        // Select affected nodes
        $sqlINString = $db->generateSQLINStatement( $userNodeIDList, 'user_node.node_id', false, false, 'int' );
        $sql = "SELECT DISTINCT user_node.node_id,
                                user_node.path_string,
                                user_tree.contentobject_id
                FROM ezcontentobject_tree user_node,
                     ezcontentobject_tree user_tree
                WHERE $sqlINString AND
                      user_node.path_string LIKE $concatString";
        $nodePart = $db->arrayQuery( $sql );

        // Remove duplicates
        $objectIDList = array();
        foreach ( $nodePart as $row )
            if ( $row['contentobject_id'] != '0' )
                $objectIDList[] = $row['contentobject_id'];
        $objectIDList = array_unique( $objectIDList );

        if ( count( $objectIDList ) == 0 )
        {
            $retValue = array();
            return $retValue;
        }

        // Select affected roles and policies
        $sqlINString = $db->generateSQLINStatement( $objectIDList, 'user_role.contentobject_id', false, false, 'int' );
        $sql = "SELECT DISTINCT user_role.contentobject_id,
                                policy.id AS policy_id,
                                user_role.limit_identifier AS limitation,
                                user_role.limit_value AS value
                FROM ezuser_role user_role,
                     ezpolicy policy
                WHERE $sqlINString AND
                      ( user_role.role_id=policy.role_id AND
                        ( policy.module_name='*' OR
                          ( policy.module_name='content' AND
                            ( policy.function_name='*' OR
                              policy.function_name='read'
                            )
                          )
                        )
                      )";
        $rolePart = $db->arrayQuery( $sql );

        // Build resultArray. Make sure there are no duplicates.
        $resultArray = array();
        foreach ( $userPart as $up )
        {
            foreach ( $nodePart as $np )
            {
                if ( $up['node_id'] == $np['node_id'] )
                {
                    foreach ( $rolePart as $rp )
                    {
                        if ( $np['contentobject_id'] == $rp['contentobject_id'] )
                        {
                            $key = $rp['policy_id'] . $up['user_id'] . $rp['limitation'] . $rp['value'];
                            $resultArray[$key] = array( 'policy_id' => $rp['policy_id'],
                                                        'user_id' => $up['user_id'],
                                                        'limitation' => $rp['limitation'],
                                                        'value' => $rp['value'] );
                        }
                    }
                }
            }
        }

        $policyIDArray = array();
        $limitedPolicyIDArray = array();
        $userIDArray = array();
        foreach( $resultArray as $result )
        {
            $userIDArray[(string)$result['user_id']] = (int)$result['user_id'];
        }

        foreach( $resultArray as $result )
        {
            if ( $result['limitation'] == '' )
            {
                $policyIDArray[(string)$result['policy_id']][] =& $userIDArray[(string)$result['user_id']];
            }
            else
            {
                $limitedPolicyIDArray[] = array( 'user_id' => $userIDArray[(string)$result['user_id']],
                                                 'limitation' => $result['limitation'],
                                                 'value' => $result['value'],
                                                 'policyID' => $result['policy_id'] );
            }
        }

        $acceptedUserArray = array();
        foreach( array_keys( $policyIDArray ) as $policyID )
        {
            foreach( array_keys( $policyIDArray[$policyID] ) as $key )
            {
                if ( $policyIDArray[$policyID][$key] === false )
                {
                    unset( $policyIDArray[$policyID][$key] );
                }
            }

            if ( count( $policyIDArray[$policyID] ) == 0 )
            {
                continue;
            }

            $userArray = eZSubtreeNotificationRule::checkObjectAccess( $contentObject, $policyID, $policyIDArray[$policyID] );
            $acceptedUserArray = array_merge( $acceptedUserArray, $userArray );

            foreach ( $userArray as $userID )
            {
                $userIDArray[(string)$userID] = false;
            }
        }

        foreach( $limitedPolicyIDArray as $policyEntry )
        {
            if ( $policyEntry['user_id'] === false )
            {
                continue;
            }

            $userArray = eZSubtreeNotificationRule::checkObjectAccess( $contentObject,
                                                                       $policyEntry['policyID'],
                                                                       array( $policyEntry['user_id'] ),
                                                                       array( $policyEntry['limitation'] => $policyEntry['value'] ) );

            $acceptedUserArray = array_merge( $acceptedUserArray, $userArray );
            foreach ( $userArray as $userID )
            {
                $userIDArray[(string)$userID] = false;
            }
        }
        $acceptedUserArray = array_unique( $acceptedUserArray );

        foreach( array_keys( $acceptedUserArray ) as $key )
        {
            if ( !is_int( $acceptedUserArray[$key] ) or $acceptedUserArray[$key] == 0 )
            {
                unset( $acceptedUserArray[$key] );
            }
        }

        if ( count( $acceptedUserArray ) == 0 )
        {
            $retValue = array();
            return $retValue;
        }

        $nodeIDWhereString = $db->generateSQLINStatement( $nodeIDList, 'rule.node_id', false, false, 'int' );
        $userIDWhereString = $db->generateSQLINStatement( $acceptedUserArray, 'rule.user_id', false, false, 'int' );
        $rules = $db->arrayQuery( "SELECT rule.user_id, rule.use_digest, ezuser.email as address
                                      FROM ezsubtree_notification_rule rule, ezuser
                                      WHERE rule.user_id=ezuser.contentobject_id AND
                                            $nodeIDWhereString AND
                                            $userIDWhereString" );
        return $rules;
    }
748527
public static function nodelist_to_array( \DOMNodeList $list ) {
		$out = [];

		foreach ( $list as $node ) {
			$out[ \spl_object_hash( $node ) ] = $node;
		}

		return $out;
	}
473339
static function fetchByIDList( $idList, $cacheInfoList = false )
    {
        if ( !$cacheInfoList )
            $cacheInfoList = eZCache::fetchList();

        $cacheList = array();
        foreach ( $cacheInfoList as $cacheInfo )
        {
            if ( in_array( $cacheInfo['id'], $idList ) )
                $cacheList[] = $cacheInfo;
        }
        return $cacheList;
    }
1199842
private function getRowValues(\DOMElement $item, int $themeId): array
    {
        $fields = $item->childNodes;
        $values = [];

        for ($index = 0; $index < $fields->length; $index++) {
            $value = $fields->item($index)->nodeValue;
            $name  = $fields->item($index)->getAttribute('name');

            switch ($name) {
                case 'id':
                    break;

                case 'pid':
                    $values[$name] = $themeId;

                    break;

                default:
                    if ($value === 'NULL') {
                        $value = null;
                    }

                    $values[$name] = $value;
            }
        }

        return $values;
    }
829505
public function swapNode( $nodeID, $selectedNodeID, $nodeIdList = array() )
    {
        $contentObject1 = eZContentObject::fetchByNodeID( $nodeID );
        $contentObject2 = eZContentObject::fetchByNodeID( $selectedNodeID );
        $this->addObject( $contentObject1 );
        $this->addObject( $contentObject2 );
    }
532187
function getBaseList( eZContentObjectVersion $objectVersion )
    {
        $returnList = array();
        // Get ezfSolrDocumentFieldBase instance for all attributes in related object
        if ( eZContentObject::recursionProtect( $this->ContentObjectAttribute->attribute( 'contentobject_id' ) ) )
        {
            foreach ( $objectVersion->contentObjectAttributes( $this->ContentObjectAttribute->attribute( 'language_code' ) ) as $attribute )
            {
                if ( $attribute->attribute( 'contentclass_attribute' )->attribute( 'is_searchable' ) )
                {
                    $returnList[] = ezfSolrDocumentFieldBase::getInstance( $attribute );
                }
            }
        }
        return $returnList;
    }
1014100
static function appendRelatingNodeIDs( $object, &$nodeIDList )
    {
        $viewCacheIni = eZINI::instance( 'viewcache.ini' );
        if ( $viewCacheIni->hasVariable( 'ViewCacheSettings', 'ClearRelationTypes' ) )
        {
            $relTypes = $viewCacheIni->variable( 'ViewCacheSettings', 'ClearRelationTypes' );

            if ( !count( $relTypes ) )
                return;

            $relatedObjects = array();

            $relationsMask = 0;
            if ( in_array( 'object', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_COMMON | eZContentObject::RELATION_EMBED;

            if ( in_array( 'common', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_COMMON;

            if ( in_array( 'embedded', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_EMBED;

            if ( in_array( 'linked', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_LINK;

            if ( in_array( 'attribute', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_ATTRIBUTE;

            if ( $relationsMask )
            {
                $objects = $object->relatedContentObjectList( false, false, false, false,
                                                              array( 'AllRelations' => $relationsMask ) );
                $previousVersionObjects = array();
                $previousVersion = $object->previousVersion();
                if ( $previousVersion )
                {
                    $previousVersionObjects = $object->relatedContentObjectList( $previousVersion, false, false, false,
                                                              array( 'AllRelations' => $relationsMask ) );
                }
                $relatedObjects = array_merge( $relatedObjects, $objects, $previousVersionObjects );
            }

            $relationsMask = 0;
            if ( in_array( 'reverse_object', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_COMMON | eZContentObject::RELATION_EMBED;

            if ( in_array( 'reverse_common', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_COMMON;

            if ( in_array( 'reverse_embedded', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_EMBED;

            if ( in_array( 'reverse_linked', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_LINK;

            if ( in_array( 'reverse_attribute', $relTypes ) )
                $relationsMask |= eZContentObject::RELATION_ATTRIBUTE;

            if ( $relationsMask )
            {
                $objects = $object->reverseRelatedObjectList( false, false, false,
                                                              array( 'AllRelations' => $relationsMask ) );
                $previousVersionObjects = array();
                $previousVersion = $object->previousVersion();
                if ( $previousVersion )
                {
                    $previousVersionObjects = $object->relatedContentObjectList( $previousVersion, false, false, false,
                                                              array( 'AllRelations' => $relationsMask ) );
                }
                $relatedObjects = array_merge( $relatedObjects, $objects, $previousVersionObjects );
            }
        }
        else
        {
            $normalRelated = $object->relatedContentObjectArray();
            $reversedRelated = $object->contentObjectListRelatingThis();

            $relatedObjects = array_merge( $normalRelated, $reversedRelated );
        }

        foreach ( $relatedObjects as $relatedObject )
        {
            $assignedNodes = $relatedObject->assignedNodes( false );
            foreach ( $assignedNodes as $assignedNode )
            {
                $nodeIDList[] = $assignedNode['node_id'];
            }
        }
        $nodeIDList = array_unique( $nodeIDList );
    }
509590
protected function createNameListDOMElementFromContentObject( DOMDocument $domDocument, eZContentObject $object )
    {
        $languageListElement = $domDocument->createElement( 'NameList' );

        // Add language names.
        foreach( $object->attribute( 'current' )->translationList( false, false ) as $locale )
        {
            $languageElement = $domDocument->createElement( 'Name' );
            $languageElement->setAttribute( 'locale', $locale );
            $languageElement->appendChild( $domDocument->createTextNode( $object->name( false, $locale ) ) );
            $languageListElement->appendChild( $languageElement );
        }

        return $languageListElement;
    }
174488
public function onAliasChange(array $nodeIdList) : void
    {
        $this->aliasManager->invalidateRelated($nodeIdList);
        $this->aliasCacheLookup->refresh();
    }
1059445
static function fetchLinkList( $contentObjectAttributeID, $contentObjectAttributeVersion, $asObject = true )
    {
        $linkList = array();

        $urlObjectLinkList = self::fetchLinkObjectList( $contentObjectAttributeID, $contentObjectAttributeVersion, $asObject );

        foreach ( $urlObjectLinkList as $urlObjectLink )
        {
            if ( $asObject )
            {
                $linkID = $urlObjectLink->attribute( 'url_id' );
                $linkList[] = eZURL::fetch( $linkID );
            }
            else
            {
                $linkID = $urlObjectLink['url_id'];
                $linkList[] = $linkID;
            }
        }
        return $linkList;
    }
269100
static function objectToOO( $nodeID )
    {
        $node = eZContentObjectTreeNode::fetch( $nodeID );

        if ( !is_object( $node ) )
        {
            return false;
        }

        $ooGenerator = new eZOOGenerator();

        $object = $node->attribute( 'object' );
        $attributes = $object->contentObjectAttributes();

        $supportedDatatypes = array( 'ezstring', 'eztext', 'ezxmltext', 'ezimage', 'ezdate', 'ezdatetime', 'ezmatrix' );

        $odfINI = eZINI::instance( 'odf.ini' );
        $ClassMappingToHeader = ( $odfINI->variable( 'ODFExport', 'ClassAttributeMappingToHeader' ) == 'enabled' ) ? true : false;

        // @bf 2008-08-21: Fetch the current class identifier and the .ini settings for the enabled attributes for this
        $classIdentifier = $object->contentClassIdentifier();
        $enabledClassAttributes = $odfINI->hasVariable( $classIdentifier, 'Attribute' ) ? $odfINI->variable( $classIdentifier, 'Attribute' ) : array();

        foreach ( $attributes as $attribute )
        {
            $datatype = $attribute->attribute( 'data_type_string' );
            $identifier = $attribute->attribute( "contentclass_attribute_identifier" );

            if ( !in_array( $datatype, $supportedDatatypes ) )
            {
                eZDebug::writeError( "Attribute '$identifier' with unsupported datatype '$datatype' for OO conversion" );
                continue;
            }

            // @bf 2008-08-21: Only export attribute if it is enabled
            if ( !array_key_exists( $identifier, $enabledClassAttributes ) )
            {
                continue;
            }

            if( !$ClassMappingToHeader )
            {
                $ooGenerator->startSection( $identifier );
            }
            else
            {
                $ooGenerator->startClassMapHeader( $identifier );
            }

            switch ( $datatype )
            {
                case "ezstring":
                {
                    $text = trim( $attribute->content() );
                    if ( $text != "" )
                    {
                        $ooGenerator->addHeader( $text );
                    }
                } break;

                case "eztext":
                {
                    $ooGenerator->addParagraph( $attribute->content() );

                } break;

                case "ezxmltext":
                {
                    $xmlData = $attribute->attribute( 'data_text' );
                    $dom = new DOMDocument( '1.0', 'UTF-8' );
                    $dom->preserveWhiteSpace = false;
                    $success = $dom->loadXML( $xmlData );
                    if ( $success )
                    {
                        $root = $dom->documentElement;
                        foreach ( $root->childNodes as $node )
                        {
                            self::handleNode( $node, $ooGenerator );
                        }
                    }
                    else
                    {
                        eZDebug::writeError( "Unable to load XML data for attribute '$identifier'" );
                    }
                } break;

                case "ezimage":
                {
                    $originalImage = $attribute->content()->attribute( 'original' );

                    $fileHandler = eZClusterFileHandler::instance( $originalImage['url'] );
                    $uniqueFile = $fileHandler->fetchUnique();

                    $imageArray = array( "FileName" => $uniqueFile,
                                         "Alignment" => "center",
                                         "DisplayWidth" => $originalImage['width'],
                                         "DisplayHeight" => $originalImage['height'] );

                    $ooGenerator->addImage( $imageArray );
                } break;

                case "ezdate":
                {
                    $date = $attribute->content();
                    $ooGenerator->addParagraph( $date->attribute( "day" ) . "/" . $date->attribute( "month" ) . "/" . $date->attribute( "year" ) );
                } break;

                case "ezdatetime":
                {
                    $date = $attribute->content();
                    $ooGenerator->addParagraph( $date->attribute( "day" ) . "/" . $date->attribute( "month" ) . "/" . $date->attribute( "year" ) . " " . $date->attribute( "hour" )  . ":" . $date->attribute( "minute" )  );
                } break;

                case "ezmatrix":
                {
                    $matrix = $attribute->content();
                    $columns = $matrix->attribute( "columns" );

                    $ooGenerator->startTable();

                    foreach ( $columns['sequential'] as $column )
                    {
                        $ooGenerator->addParagraph( $column['name'] );
                        $ooGenerator->nextCell();
                    }

                    $ooGenerator->nextRow( "defaultstyle" );

                    $rows = $matrix->attribute( "rows" );

                    foreach ( $rows['sequential'] as $row )
                    {
                        foreach ( $row['columns'] as $cell )
                        {
                            $ooGenerator->addParagraph( $cell );
                            $ooGenerator->nextCell();
                        }
                        $ooGenerator->nextRow( "defaultstyle" );
                    }

                    $ooGenerator->endTable();
                } break;
            }

            if( !$ClassMappingToHeader )
            {
                $ooGenerator->endSection();
            }
        }

        return $ooGenerator->writeDocument();
    }
863504
protected static function getFirstAndValidateType(NodeList $list, string $expectedType): Node
    {
        if ($list->count() !== 1) {
            throw new ParseException('More than one definition was found in the passed in schema.');
        }

        $node = $list[0];

        return self::validateType($node, $expectedType);
    }
486457
static function fetchNodePathString( $nodeList )
    {
        $pathList = array();
        foreach ( $nodeList as $node )
        {
            $pathList[] = $node->attribute( 'path_string' );
        }
        return $pathList;
    }
13980
public function getSubTreeLimitations()
    {
        if ( $this->attribute( 'main_tag_id' ) != 0 )
            return array();

        return parent::fetchObjectList( eZContentClassAttribute::definition(), null,
                                                    array( 'data_type_string'              => 'eztags',
                                                           eZTagsType::SUBTREE_LIMIT_FIELD => $this->attribute( 'id' ),
                                                           'version'                       => eZContentClass::VERSION_STATUS_DEFINED ) );
    }
690478
function preloadDependencies(array $nodeIdList)
    {
        $siteIdList = [];

        $nodeList = parent::preloadDependencies($nodeIdList);

        foreach ($nodeList as $node) {
            foreach ($node->ucms_sites as $siteId) {
                $siteIdList[$siteId] = $siteId;
            }
        }

        if ($siteIdList) {
            $this->siteManager->getStorage()->loadAll($siteIdList);
        }

        return $nodeList;
    }
682424
function subTree( $params, $nodeID, $countChildren = false )
    {
        $nodeListArray = array();

        // sorting params
        $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $params['SortBy'] );

        // node params
        $notEqParentString = '';
        $pathStringCond    = '';
        eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, 1, false );

        // class filter
        $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString( $params['ClassFilterType'], $params['ClassFilterArray'] );
        if ( $classCondition === false )
        {
            return $nodeListArray;
        }

        // permissions
        $limitationParams = false;
        $limitationList = eZContentObjectTreeNode::getLimitationList( $limitationParams );

        if ( $limitationList === false )
        {
            return $nodeListArray;
        }

        $permissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );

        // invisible nodes.
        $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( false, $params['FetchHidden'] );

        $query = '';
        if ( $countChildren )
        {
            $query = "SELECT count(*) as count
                          FROM
                               ezcontentobject_tree
                               INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id)
                               INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)
                               INNER JOIN ezcontentobject_name ON (
                                   ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND
                                   ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version
                               )
                               $permissionChecking[from]
                          WHERE $pathStringCond
                                $classCondition
                                ezcontentclass.version=0 AND
                                $notEqParentString
                                " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . "
                                $permissionChecking[where] ";
        }
        else
        {
            $query = "SELECT ezcontentobject.*,
                             ezcontentobject_tree.*,
                             ezcontentclass.serialized_name_list as class_serialized_name_list,
                             ezcontentclass.identifier as class_identifier,
                             ezcontentclass.is_container as is_container,
                             ezcontentobject_name.name as name,
                             ezcontentobject_name.real_translation
                      FROM
                             ezcontentobject_tree
                             INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id)
                             INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)
                             INNER JOIN ezcontentobject_name ON (
                                 ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND
                                 ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version
                             )
                             $sortingInfo[attributeFromSQL]
                             $permissionChecking[from]
                      WHERE
                             $pathStringCond
                             $sortingInfo[attributeWhereSQL]
                             ezcontentclass.version=0 AND
                             $notEqParentString
                             $classCondition
                             ezcontentobject_tree.contentobject_is_published = 1 AND
                             " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . "
                             $showInvisibleNodesCond
                             $permissionChecking[where]
                      ORDER BY $sortingInfo[sortingFields]";

        }

        $db = eZDB::instance();
        $nodeListArray = $db->arrayQuery( $query );

        // cleanup temp tables
        $db->dropTempTableList( $permissionChecking['temp_tables'] );

        if ( $countChildren )
        {
            return $nodeListArray[0]['count'];
        }
        else
        {
            foreach ( $nodeListArray as $key => $row )
            {
                $nodeListArray[$key]['path_identification_string'] = eZContentObjectTreeNode::fetch( $row['node_id'] )->pathWithNames();
            }
            return $nodeListArray;
        }
    }
1356382
protected function preloadDependencies(array $nodeIdList)
    {
        $userIdList = [];
        $nodeList = $this->entityManager->getStorage('node')->loadMultiple($nodeIdList);

        foreach ($nodeList as $node) {
            $userIdList[$node->uid] = $node->uid;
        }

        if ($userIdList) {
            $this->entityManager->getStorage('user')->loadMultiple($userIdList);
        }

        return $nodeList;
    }