Trying to work on a recurring meeting feature in Espo and need help

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nocstaff@urbancom.net
    Member
    • Jul 2025
    • 80

    #1

    Trying to work on a recurring meeting feature in Espo and need help

    Since espo doesn't come with an ability to make recurring calendar, I was trying to make one myself. So far progress has been going alright, but I ran into a problem. It duplicates any meeting I try making, I don't know what is causing this, so I will share everything I've been working on and screenshots of the process to show what I've done so far.

    I made a base for recurring calendar items, which will be extended for each calendar item I want this to work with in /var/www/espocrm/data/espocrm/custom/Espo/Custom/Hooks/Common/RecurringBase.php:

    PHP Code:
    <?php

    namespace Espo\Custom\Hooks\Common;

    use 
    Espo\ORM\Entity;
    use 
    Espo\Core\Hook\Hook\AfterSave;
    use 
    Espo\ORM\EntityManager;
    use 
    Espo\ORM\Repository\Option\SaveOptions;

    class 
    RecurringBase implements AfterSave
    {
        protected 
    EntityManager $em;

        public function 
    __construct(EntityManager $em)
        {
            
    $this->em $em;
        }

        public function 
    afterSave(Entity $entitySaveOptions $options): void
        
    {
            
    // Skip if not recurring or if already a generated child
            
    if (!$entity->get('repeat') || $options->get('isRecurringChild') === true) {
                return;
            }

            
    $startDate = new \DateTime($entity->get('dateStart'));
            
    $endDate   = new \DateTime($entity->get('dateEnd'));
            
    $until     $entity->get('repeatUntil') ? new \DateTime($entity->get('repeatUntil')) : null;

            
    $interval  = (int) $entity->get('repeatInterval') ?: 1;
            
    $repeat    $entity->get('repeat');

            
    $count 0;
            
    $max   200;

            while (
    true) {
                
    $count++;

                
    $newStart = (clone $startDate);
                
    $newEnd   = (clone $endDate);

                switch (
    $repeat) {
                    case 
    'Daily':
                        
    $newStart->modify("+{$interval} days");
                        
    $newEnd->modify("+{$interval} days");
                        break;
                    case 
    'Weekly':
                        
    $newStart->modify("+{$interval} weeks");
                        
    $newEnd->modify("+{$interval} weeks");
                        break;
                    case 
    'Monthly':
                        
    $newStart->modify("+{$interval} months");
                        
    $newEnd->modify("+{$interval} months");
                        break;
                    default:
                        return;
                }

                if (
    $until && $newStart $until) {
                    break;
                }

                
    $duplicate $this->em->getEntityFactory()->create($entity->getEntityType());

                foreach ([
                    
    'name','description','status',
                    
    'assignedUserId','teamsIds',
                    
    'parentId','parentType',
                    
    'allDay','reminders'
                
    ] as $f) {
                    if (
    $entity->has($f)) {
                        
    $duplicate->set($f$entity->get($f));
                    }
                }

                
    $duplicate->set('dateStart'$newStart->format('Y-m-d H:i:s'));
                
    $duplicate->set('dateEnd',   $newEnd->format('Y-m-d H:i:s'));

                
    // Clear recurrence so children don’t recurse
                
    $duplicate->set('repeat'null);
                
    $duplicate->set('repeatInterval'null);
                
    $duplicate->set('repeatUntil'null);

                
    // Save with flag
                
    $this->em->saveEntity($duplicate, ['isRecurringChild' => true]);

                if (
    $count >= $max) {
                    break;
                }

                
    $startDate $newStart;
                
    $endDate   $newEnd;
            }
        }
    }
    And in /var/www/espocrm/data/espocrm/custom/Espo/Custom/Hooks/Meeting/Recurring.php:

    PHP Code:
    <?php

    namespace Espo\Custom\Hooks\Meeting;

    use 
    Espo\Custom\Hooks\Common\RecurringBase;

    class 
    Recurring extends RecurringBase {}
    I will be completely honest, I don't really understand how coding works in espo, my knowledge of php is very limited, and espo is very difficult to understand, so I've just been using a lot of reference material to get to where I am. I uploaded screenshots of what the process looks like and what the results are currently, and I circled the part I added into espo myself. I don't know what is causing the meeting to duplicate twice a day instead of once. This also happens when you select weekly or monthly. Can someone help me with this please?
    Attached Files
    Last edited by nocstaff@urbancom.net; 10-01-2025, 04:31 PM.
Working...