| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | <?php/** * @file * Contains the CerFieldChainHandler object. *//** * @class * Wraps around every CerFieldHandler object in a chain. In any given chain, there * could be many entities that need to be processed -- think about multi-value field * collections embedded within other multi-value field collections, and you quickly * see how extensive the recursion can be. CER needs to be able to handle crazy * scenarios like that and still perform add/delete operations transparently. That's * what this guy does. */class CerFieldChainHandler {  /**   * @var CerFieldChain   */  protected $chain;  /**   * @var EntityDrupalWrapper   */  protected $entity;  /**   * @var array or RecursiveIteratorIterator   */  protected $handlers;  public function __construct(CerFieldChain $chain, EntityDrupalWrapper $entity) {    $this->chain = $chain;    $this->entity = $entity;    $chain->__wakeup();    $chain->seek($entity->cer->depth->value());    $field = $chain->current();    // If the field has a child, there could be extensive recusion here. So we'll need    // to iterate over the entire chain recursively -- luckily, SPL provides the    // RecursiveIteratorIterator class for this purpose. But if there are no children,    // we don't need to recurse; the only handler we'll need to load is the current    // field's, for the current entity.    if ($field->child()) {      $this->handlers = new RecursiveIteratorIterator(new CerEndPointIterator($field, $entity));    }    else {      // Wrap the handler in an array, just to normalize things internally.      $this->handlers = array( $field->getHandler($entity) );    }  }  /**   * Returns the IDs of every entity referenced in this chain. If there are no references,   * an empty array is returned.   *   * @return array   */  public function getIDs() {    $IDs = array();    foreach ($this->handlers as $handler) {      $IDs = array_merge($handler->getIDs(), $IDs);    }    return array_unique($IDs);  }  /**   * Adds a reference to the given entity.   */  public function add(EntityDrupalWrapper $entity) {    $owner = $this->entity;    foreach ($this->chain as $field) {      // If the current field implements CerEntityContainerInterface, we can      // create an entity on-the-fly to receive the reference, if there isn't      // one already.      if ($field instanceof CerEntityContainerInterface) {        $items = $field->getHandler($owner);        // If there is are items which could receive the reference, seek to the        // last one. Otherwise, create one.        if (sizeof($items) == 0) {          $owner = $field->createInnerEntity($owner);        }        else {          $items->seek(-1);          $owner = $items->current();        }      }    }    $field->getHandler($owner)->add($entity);  }  public function delete(EntityDrupalWrapper $entity) {    foreach ($this->handlers as $handler) {      $handler->delete($entity);    }  }}
 |