@@ -3263,6 +3263,9 @@ public static function addDocument(
32633263
32643264 // Document already exists
32653265 if (null !== $ document ) {
3266+ // Keep the contextual tree consistent: set ResourceLink.parent when needed.
3267+ self ::syncResourceLinkParentForContext ($ document , $ parentResource , $ courseEntity , $ session , $ group );
3268+
32663269 return $ document ;
32673270 }
32683271
@@ -3281,6 +3284,9 @@ public static function addDocument(
32813284 $ em ->persist ($ document );
32823285 $ em ->flush ();
32833286
3287+ // Ensure contextual hierarchy (course/session/group) uses ResourceLink.parent.
3288+ self ::syncResourceLinkParentForContext ($ document , $ parentResource , $ courseEntity , $ session , $ group );
3289+
32843290 $ repo = Container::getDocumentRepository ();
32853291 if (!empty ($ content )) {
32863292 $ repo ->addFileFromString ($ document , $ title , 'text/html ' , $ content , true );
@@ -3318,4 +3324,108 @@ public static function addDocument(
33183324
33193325 return false ;
33203326 }
3327+
3328+ private static function syncResourceLinkParentForContext (
3329+ CDocument $ child ,
3330+ $ parentResource ,
3331+ $ courseEntity ,
3332+ $ session ,
3333+ $ group
3334+ ): void {
3335+ // Only set a parent link when the parent is another document (folder).
3336+ if (!$ parentResource instanceof CDocument) {
3337+ return ; // Root items must keep rl.parent = NULL
3338+ }
3339+
3340+ if (!method_exists ($ child , 'getResourceNode ' ) || !method_exists ($ parentResource , 'getResourceNode ' )) {
3341+ return ;
3342+ }
3343+
3344+ $ childNode = $ child ->getResourceNode ();
3345+ $ parentNode = $ parentResource ->getResourceNode ();
3346+
3347+ if (!$ childNode instanceof ResourceNode || !$ parentNode instanceof ResourceNode) {
3348+ return ;
3349+ }
3350+
3351+ try {
3352+ $ em = Database::getManager ();
3353+
3354+ $ childLink = self ::findResourceLinkForContext ($ em , $ childNode , $ courseEntity , $ session , $ group );
3355+ $ parentLink = self ::findResourceLinkForContext ($ em , $ parentNode , $ courseEntity , $ session , $ group );
3356+
3357+ if (!$ childLink instanceof ResourceLink || !$ parentLink instanceof ResourceLink) {
3358+ // If a link is missing, we don't hard-fail the import.
3359+ error_log ('[IMPORT] ResourceLink not found for context when syncing parent. ' , [
3360+ 'childNodeId ' => method_exists ($ childNode , 'getId ' ) ? $ childNode ->getId () : null ,
3361+ 'parentNodeId ' => method_exists ($ parentNode , 'getId ' ) ? $ parentNode ->getId () : null ,
3362+ ]);
3363+
3364+ return ;
3365+ }
3366+
3367+ $ currentParent = method_exists ($ childLink , 'getParent ' ) ? $ childLink ->getParent () : null ;
3368+
3369+ // Avoid useless flushes
3370+ if ($ currentParent && method_exists ($ currentParent , 'getId ' ) && method_exists ($ parentLink , 'getId ' )) {
3371+ if ((int ) $ currentParent ->getId () === (int ) $ parentLink ->getId ()) {
3372+ return ;
3373+ }
3374+ }
3375+
3376+ $ childLink ->setParent ($ parentLink );
3377+ $ em ->persist ($ childLink );
3378+ $ em ->flush ();
3379+ } catch (\Throwable $ e ) {
3380+ error_log ('[IMPORT] Failed to sync ResourceLink.parent for context: ' .$ e ->getMessage ());
3381+ }
3382+ }
3383+
3384+ private static function findResourceLinkForContext (
3385+ $ em ,
3386+ ResourceNode $ node ,
3387+ $ courseEntity ,
3388+ $ session ,
3389+ $ group
3390+ ): ?ResourceLink {
3391+ try {
3392+ $ qb = $ em ->createQueryBuilder ()
3393+ ->select ('rl ' )
3394+ ->from (ResourceLink::class, 'rl ' )
3395+ ->andWhere ('rl.resourceNode = :node ' )
3396+ ->setParameter ('node ' , $ node );
3397+
3398+ // Course context
3399+ if ($ courseEntity ) {
3400+ $ qb ->andWhere ('rl.course = :course ' )->setParameter ('course ' , $ courseEntity );
3401+ } else {
3402+ $ qb ->andWhere ('rl.course IS NULL ' );
3403+ }
3404+
3405+ // Session context
3406+ if ($ session ) {
3407+ $ qb ->andWhere ('rl.session = :session ' )->setParameter ('session ' , $ session );
3408+ } else {
3409+ $ qb ->andWhere ('rl.session IS NULL ' );
3410+ }
3411+
3412+ // Group context
3413+ if ($ group ) {
3414+ $ qb ->andWhere ('rl.group = :group ' )->setParameter ('group ' , $ group );
3415+ } else {
3416+ $ qb ->andWhere ('rl.group IS NULL ' );
3417+ }
3418+
3419+ $ qb ->setMaxResults (1 );
3420+
3421+ /** @var ResourceLink|null $link */
3422+ $ link = $ qb ->getQuery ()->getOneOrNullResult ();
3423+
3424+ return $ link ;
3425+ } catch (\Throwable $ e ) {
3426+ error_log ('[IMPORT] Failed to find ResourceLink for context: ' .$ e ->getMessage ());
3427+
3428+ return null ;
3429+ }
3430+ }
33213431}
0 commit comments