Create new object from existent object in DB using Symfony2 and Doctrine2 - symfony

I need to create a new set of DB records by using same data that already exists. See image below:
Using this as example I need to create the same set of records but just changing the column company, less take UPC = I5TYF1UPORMYUY4JT21Z, using this info I should be able to generate two rows by just changing the company to 52 (any number). What I think is to get those records using this:
$entityStockDetailHasProductDetail = $this->getDoctrine()->getManager()->getRepository('ProductBundle:StockDetailHasProductDetail')->findBy(array(
"product" => $request->request->get('product')['id'],
"upc" => $request->request->get('product')['upc'],
));
Which returns the right records but I don't know how to continue from that point. My entity has all this methods:
$entityStockDetailHasProductDetail->setProductDetail();
$entityStockDetailHasProductDetail->setUpc();
$entityStockDetailHasProductDetail->setProduct();
$entityStockDetailHasProductDetail->setCompany();
$entityStockDetailHasProductDetail->setCondition();
$entityStockDetailHasProductDetail->setContent();
Any ideas?

Just loop over the collection, clone your entities, set the new company and persist.
$em = $this->getDoctrine()->getEntityManager('default');
$collection = $em->getRepository('YourBundle:Entity')->findBy(array('...'));
foreach ($collection as $entity) {
$newEntity = clone $entity;
$newEntity
->setId(null)
->setCompany($company)
;
$em->persist($newEntity);
}
$em->flush();

Related

Recover data from two classes into many to many

I have a User table and a Library table, the relationship between them are many to many.
So I have a user_library table.
I manage to add data to the Library table from User but I cannot recover the data afterwards.
I add them like this:
$em = $this->getDoctrine()->getManager();
$repoUser = $em->getRepository('App:User');
$user = $repoUser->findOneBy(['token' => $token_user]);
$library = new Library();
$library->setIdBook($id_book);
$user->addLibrary($library);
$em->persist($library);
$em->persist($user);
$em->flush();
I thought that simply doing: $user->getLibrary()->getIdBook() would be enough but it is not the case.
How do you think I can get all the id_book that match the user?
The thing is that your getLibrary returns ArrayCollection, you need to specify which Library you exactly want
$libararies = $user->getLibrary() // <- this returns ArrayCollection
$library = $libraries->first() // <- return 1st element
Based on this code you can do a search for example, or just use doctrine to fetch library with desired ID, user, whatever you need straight from the database
EDIT
Lets say you want all libraries that are in relation with user with ID = 4
... // your code
$user = $this->getDoctrine()->getRepository('your user class')->find(4); // here we find your user from DB
$libraries = $user->getLibrary() // here we get all libraries which are in relation with user #4, you might want to rename the function as it returns ArrayCollection of Libraries, not Library
$bookIds = array();
foreach($libraries as $library) {
$bookIds[] = $library->getIdBook();
}
dump($bookIds); // all user #4 book ids
die;

Merging many collections in a single one symfony

(using Symfony 3.4)
I am trying to create an array collection by merging (getting only the objects) multiple collections. Sounds weird, let me explain.
I take all the users from the db and for each one I want to add in a single array collection all his/her licenses. My code:
$users = $this->userRepository->findAllUsers($params);
$users->forAll(function (User $user) use (&$array) {
$array = array_merge($array, $user->getLicenses());
});
$a = new ArrayCollection($array);
How should I resolve this?
You can merge collections like this (from How to merge two php Doctrine 2 ArrayCollection()):
$collection3 = new ArrayCollection(
array_merge($collection1->toArray(), $collection2->toArray())
);
So that can be applied to your case:
$users = $this->userRepository->findAllUsers($params);
$licensesArray = [];
foreach ($user in $users) {
$licensesArray = array_merge($licencesArray, $user->getLicenses()->toArray());
});
$licenses = new ArrayCollection($licensesArray);
This can result in having same license entity in the resulting collection several times. If that is not wanted, you can write some custom filtering to the array - or just create a repository getter for getting the licenses based on the user ids / user search params...

Doctrine migrations add new column uniquie

I want add a new column with uniquie=true but every time get duplicate values '' , this column i want to be not null. How can i construct a migration to do that, i was try many ways but i read only if have my update query in function up this query will be loaded. but in function postUp i set my unique fields vales.
This i was trying but not working:
public function postUp(Schema $schema){
$users = $this->container->get('doctrine')->getRepository('AppBundle:Users')->findAll();
foreach($users as $user){
$user->setAffiliatesToken(uniqid().str_replace(' ','',str_replace('.','',microtime())));
}
$this->addSql('CREATE UNIQUE INDEX UNIQ_1483A5E952C22EB5 ON users (affiliates_token)');
$this->addSql('CREATE INDEX IDX_1483A5E99F12C49A ON users (affiliate_id)');
$this->container->get('doctrine')->getManager()->flush();
}

Symfony2, Doctrine, Updation OneToMany entries

i have function
private function updateCharacters($oApiKeyInfo) // argument is base entity
{
$aXmlCharacter = $this->fXml->getXmlRowset($this->oXml, 'row');
// insert new
foreach ($aXmlCharacter as $oXmlCharacter)
{
$loopData = $this->fXml->getXmlAttributesAsArray($oXmlCharacter);
$oApiKeyInfoCharacters = new apiKeyInfoCharacters();
$oApiKeyInfoCharacters
->setKeyID($this->keyID)
->setCharacterID($loopData['characterID'])
->setCharacterName($loopData['characterName'])
->setCorporationID($loopData['corporationID'])
->setCorporationName($loopData['corporationName'])
->set_apiKeyInfo_byKeyID($oApiKeyInfo);
$this->em->persist($oApiKeyInfoCharacters);
}
// $this->em->flush() is in main (public) function
}
but, it creates dublicates... and i want that in db was ONLY that entries that is in $aXmlCharacter (array), others must be deleted
now code above is only adding new entries, but i need remove previous
can someone help to deal with it? and please show working examples
Dublicate entries i can not see any definition for uniquenes.
Deleting an Object vom database is simple as the documentation shows.
$product = $em->getRepository('YourBundle::apiKeyInfoCharacters')->find($id);
$em->remove($product);
$em->flush();
But why do you want to delete the existing one instead of updating?

Magento: how to merge two product collections into one?

if i have two product collections is there a way to merge them into one?
for example (my final intent isn't to actually just get a collection of 2 cats, this is just to illustrate the issue):
$collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
$collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();
$merged_collection = merge_collections($collection1,$collection2);
any help would be appreciated!
Assuming the items you wish to group together are of the same type and exist in the database then you can do this:
$collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
$collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();
$merged_ids = array_merge($collection1->getAllIds(), $collection2->getAllIds());
// can sometimes use "getLoadedIds()" as well
$merged_collection = Mage::getResourceModel('catalog/product_collection')
->addFieldToFilter('entity_id', array('in' => $merged_ids))
->addAttributeToSelect('*');
Here I know to filter by entity_id because that is products' key field, like it is for most entity types, some flat tables have a different primary key. Often you can generalise that with one of the collection's getIdFieldName() method. Products are a bad example in this case because it's ID field name isn't filled out correctly.
Almost every (or every?) collection in Magento inherits from a Varien Data Collection. A collection is a special object that holds objects of another type. There's no method for merging collections, but you can add additional items of the appropriate type to the collection.
Code like this should get you where you want to go, although there's probably more efficient ways to loop and do the actual merging.
$collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
$collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();
//load an empty collection (filter-less collections will auto-lazy-load everything)
$merged = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('entity_id',-1);
//add items from the first collection
foreach($collection1 as $item)
{
$merged->addItem($item);
}
//add items from the second collection
foreach($collection2 as $item)
{
//magento won't let you add two of the same thing to a collection
//so make sure the item doesn't already exist
if(!$merged->getItemById($item->getId()))
{
$merged->addItem($item);
}
}
//lets make sure we got something
foreach($merged as $product)
{
var_dump($product->getName());
}
I don't think there is such a method, but you can probably do something like that :
foreach ($collection1 as $item){
$collection2->addElem($item);
}
you can filter your collection directly without using 2.
$products = Mage::getModel('catalog/product');
$_collection = $products->getCollection();
->addCategoryFilter(2)
->load();
or try using 'addItem' to add your results to a collection. See also in Magento wiki
for the collection of products of several categories, you can use the following code
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('name')
->addAttributeToSelect('sku');
$collection->getSelect()
->join(
'catalog_category_product',
'product_id=entity_id',
array('category_id')
)
->where('catalog_category_product.category_id IN (?)', $categories);

Resources