Deleting items from a Doctrine_Collection

3.7k Views Asked by At

Using Doctrine 1.2, I am having some issues deleting items from a Doctrine_Collection.

I have a Doctrine collection filled with transient Doctrine_Records. The $record->delete() and $record->unlink() functions don't seem to work properly here, as they use the record's IDs. (Which transient records don't have, since they don't appear in the database yet.)

Example (in which Company has many Employee)

/* Get a Company that has no Employees yet. */
$company = Doctrine::getTable('Company')->find(1);

/* Add some Employees */
$names = array('Arthur','Bob','Charlie');

foreach ($names as $name) 
{
    $employee = new Employee;
    $employee->name = "Arthur"
    $company->Employee->add($employee);
}

Now, before saving anything to the database, I have one employee in $emp, which I want to remove from the collection.

$emp->delete() /* Does not work when $emp is transient. */

What does work is this, but I really doubt that is the way to go.

foreach($company->Employee as $key => $value)
    if ($emp == $value) 
    {
        $company->Employee->remove($key);
        break;
    }

This doesn't feel like the easiest way to do this. Is there a more recommended way of doing this?

1

There are 1 best solutions below

0
On BEST ANSWER

I ended up creating a subclass for Doctrine_Collection, and implemented this function, which gave me exactly the behaviour I wanted.

   /**
    * Looks up a Doctrine_Record in the collection, and - when found - removes it. It is also compatible with serialised records, as 
    * it tries strict matching (using ===) as well as loose matching (using ==). A strict match precedes a loose match.
    */
   public function removeItem($item)
   {
      if (!($item instanceof Doctrine_Record)) 
      {
         throw new Exception("Error while calling removeItem, trying to remove an item that does not descend from Doctrine_Record");
         return;
      }

      foreach ($this as $key=>$value)
      {
         if ($item === $value)
         {
            /* Strict match found, remove it and return. */
            $this->remove($key);
            return;
         }
         if ($looseMatch === null && $item == $value) $looseMatch = $key;
      }

      /* No strict match found. If a $matchLoose is on, and aloose match was found, remove it. */
      if ($looseMatch !== null) 
      {
         $this->remove($looseMatch);
      } 
      else throw new Exception('No match found trying to remove an item from a collection.');

   }