예제 #1
0
 /**
  * Returns a new duplicate copy of the entity
  */
 public function duplicate($flushdb = true, &$translations = array(), &$entityMap = array(), $excludeFields = array())
 {
     $metadata = $this->metadata();
     $class = $metadata->getName();
     $fieldNames = $metadata->getFieldNames();
     $associationNames = $metadata->getAssociationNames();
     $duplicate = new $class();
     $isTree = $this->isTreeNode();
     if ($class::_static()) {
         throw new \Exception($class::singular() . ' is a static type and cannot be duplicated');
     }
     // Copy field names across
     foreach ($fieldNames as $fieldName) {
         if (in_array($fieldName, $excludeFields)) {
             continue;
         }
         $value = $this->get($fieldName);
         $duplicate->set($fieldName, $value);
     }
     // Copy associations across
     foreach ($associationNames as $associationName) {
         if (in_array($associationName, $excludeFields)) {
             continue;
         }
         $associationMapping = $metadata->getAssociationMapping($associationName);
         $value = $this->get($associationName);
         $shouldCopy = $associationMapping['orphanRemoval'] || $associationMapping['isCascadeRemove'];
         $isTreeChildren = $isTree && $associationName == 'children';
         $targetPropName = $associationMapping['isOwningSide'] ? @$associationMapping['inversedBy'] : @$associationMapping['mappedBy'];
         if (!empty($value) && ($shouldCopy || $isTreeChildren)) {
             if ($metadata->isCollectionValuedAssociation($associationName)) {
                 $duplicateCollection = array();
                 foreach ($value as $item) {
                     $itemClass = $item->metadata()->name;
                     if (!$itemClass::_static()) {
                         $duplicateItem = $item->duplicate(false, $translations, $entityMap, array($targetPropName));
                         if (!empty($duplicateItem)) {
                             $duplicateCollection[] = $duplicateItem;
                         }
                     }
                 }
                 $value = $duplicateCollection;
             } else {
                 $itemClass = $value->metadata()->name;
                 if (!$itemClass::_static()) {
                     $value = $value->duplicate(false, $translations, $entityMap, array($targetPropName));
                 } else {
                     $value = null;
                 }
             }
         }
         $duplicate->set($associationName, $value);
     }
     if (!$flushdb) {
         \D::manager()->persist($duplicate);
     }
     // If languages are enabled, add its translations to the array reference using the new oid
     if ($this->id && \CMF::langEnabled()) {
         $oid = spl_object_hash($duplicate);
         $entityMap[$oid] = $duplicate;
         if (!isset($translations[$oid])) {
             $translations[$oid] = \DB::query("SELECT * FROM ext_translations WHERE object_class = '{$metadata->rootEntityName}' AND foreign_key = '{$this->id}'")->execute()->as_array();
         }
     }
     if ($flushdb) {
         // Persist the item
         if ($isTree) {
             $class::repository()->persistAsNextSiblingOf($duplicate, $this);
         } else {
             \D::manager()->persist($duplicate);
         }
         $displayField = $this->findFieldUsedInDisplay();
         if (!empty($displayField)) {
             $duplicate->setUniqueValueForField($displayField);
         }
         \D::manager()->flush();
         // Add translations after all the entities have been committed to the db
         if (!empty($translations)) {
             foreach ($translations as $objectHash => $objectTranslations) {
                 $entity = isset($entityMap[$objectHash]) ? $entityMap[$objectHash] : null;
                 if (empty($entity) || empty($entity->id) || empty($objectTranslations)) {
                     continue;
                 }
                 $cols = null;
                 $qb = \DB::insert('ext_translations');
                 foreach ($objectTranslations as $translation) {
                     unset($translation['id']);
                     $translation['foreign_key'] = strval($entity->id);
                     if (is_null($cols)) {
                         $cols = array_keys($translation);
                         $qb->columns($cols);
                     }
                     // Insert the new translations
                     $qb->values($translation);
                 }
                 $qb->execute();
             }
         }
         try {
             if (is_subclass_of($class, 'CMF\\Model\\Node')) {
                 $repo = \D::manager()->getRepository($class);
                 $repo->recover();
                 \D::manager()->flush();
             }
         } catch (\Exception $e) {
         }
     }
     return $duplicate;
 }