Magento 2: get Stock quantity from custom source - magento2

I use this code to retrieve stock quantity by product id.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
$qty = $StockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
This snippet returns only "default source" quantity.
My goal consist to retrieve "mycustom source" quantity such as:
Is it possible?

Sure. See below codes:
<?php
namespace YourNameSpace;
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
class YourClass
{
/**
* #var SourceItemRepositoryInterface
*/
protected SourceItemRepositoryInterface $sourceItems;
/**
* #var SearchCriteriaBuilder
*/
protected SearchCriteriaBuilder $searchCriteriaBuilder;
/**
* #param SourceItemRepositoryInterface $sourceItems
* #param SearchCriteriaBuilder $searchCriteriaBuilder
*/
public function __construct(
SourceItemRepositoryInterface $sourceItems,
SearchCriteriaBuilder $searchCriteriaBuilder
){
$this->sourceItems = $sourceItems;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
}
public function yourFunction() {
//Set source
$sku = $product->getSku();
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('sku', $sku)
->create();
$sourceItemData = $this->sourceItems->getList($searchCriteria);
foreach ($sourceItemData->getItems() as $sourceItem){
//Get source qty
$sourceItem->getQuantity()
//Get source code
$sourceItem->getSourceCode();
}
}
}
}
You just need to provide SKU, and then you will get 8 from MyCustom Source and 47 from Default Source. I simplified the codes to be a more readable form, please modify it when you use them.

Related

How to Get Value from Index controller to Collection in Magento 2

I'm trying to get the value from Index controller.
Controller\Adminhtml\Orders\Index.php :
public function execute()
{
$storeid = $this->getRequest()->getParam('storeid');
$this->settings->setStoreid($storeid);
}
Model\Settings.php
public function setStoreid($storeid)
{
$this->storeid = $storeid;
}
public function getStoreid()
{
return $this->storeid;
}
Model\ResourceModel\Order\Grid\Collection.php :
public function _renderFiltersBefore{
$storeid = $this->getStoreId();
// var_dump($storeid)
// $storeid = 5
$this->getSelect()->where('store_id = ?', $storeid);
}
I want to pass the storeid to the query Collection. I can able to set the storeid from Index class and can able to get the storeid in Collection class. But it doesnt passing to the collection.
If I set the value directly to storeid, ie. $storeid = 5, then collection works fine. Please advice.
Maybe try to use registry
/**
* #var \Magento\Framework\Registry
*/
protected $_registry;
/**
* ...
* ...
* #param \Magento\Framework\Registry $registry,
*/
public function __construct(
...,
...,
\Magento\Framework\Registry $registry,
...
) {
$this->_registry = $registry;
...
...
}
/**
* Setting custom variable in registry to be used
*
*/
public function setCustomVariable()
{
$this->registry->register('custom_var', 'Added Value');
}
/**
* Retrieving custom variable from registry
* #return string
*/
public function getCustomVariable()
{
return $this->registry->registry('custom_var');
}

How to attach invoice PDF instead of packing slip in magento 2

I want to attach invoice pdf instead of packing slip while creating shipment.
I am using Fooman Email attachment extension version 2.0.8
My magento is 2.2.5 Can anyone know how can I change the attched PDF in shipping confirmation mail ?
Currently it is attaching packing slip but I want to attach invoice pdf in shipping confirmation mail.
We had a similar problem using fooman. We also wanted to send our invoice on shipment creation, while disableing the standard transactional invoice mail on invoice creation. I wrote a module that sends the invoice email together with the shipping email, which is not exactly what you are looking for but maybe you can leverage that.
The module is pretty simple. Except from boilerplate registration.php and module.xml, all you need is to override InvoiceOrder from Magento\Sales\Model and comment out this line:
$this->notifierInterface->notify($order, $invoice, $comment);
like so:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model;
use Magento\Framework\App\ResourceConnection;
use Magento\Sales\Api\Data\InvoiceCommentCreationInterface;
use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface;
use Magento\Sales\Api\InvoiceOrderInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order\Config as OrderConfig;
use Magento\Sales\Model\Order\Invoice\NotifierInterface;
use Magento\Sales\Model\Order\InvoiceDocumentFactory;
use Magento\Sales\Model\Order\InvoiceRepository;
use Magento\Sales\Model\Order\OrderStateResolverInterface;
use Magento\Sales\Model\Order\PaymentAdapterInterface;
use Magento\Sales\Model\Order\Validation\InvoiceOrderInterface as InvoiceOrderValidator;
use Psr\Log\LoggerInterface;
/**
* Class InvoiceOrder
* #SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class InvoiceOrder implements InvoiceOrderInterface
{
/**
* #var ResourceConnection
*/
private $resourceConnection;
/**
* #var OrderRepositoryInterface
*/
private $orderRepository;
/**
* #var InvoiceDocumentFactory
*/
private $invoiceDocumentFactory;
/**
* #var PaymentAdapterInterface
*/
private $paymentAdapter;
/**
* #var OrderStateResolverInterface
*/
private $orderStateResolver;
/**
* #var OrderConfig
*/
private $config;
/**
* #var InvoiceRepository
*/
private $invoiceRepository;
/**
* #var InvoiceOrderValidator
*/
private $invoiceOrderValidator;
/**
* #var NotifierInterface
*/
private $notifierInterface;
/**
* #var LoggerInterface
*/
private $logger;
/**
* InvoiceOrder constructor.
* #param ResourceConnection $resourceConnection
* #param OrderRepositoryInterface $orderRepository
* #param InvoiceDocumentFactory $invoiceDocumentFactory
* #param PaymentAdapterInterface $paymentAdapter
* #param OrderStateResolverInterface $orderStateResolver
* #param OrderConfig $config
* #param InvoiceRepository $invoiceRepository
* #param InvoiceOrderValidator $invoiceOrderValidator
* #param NotifierInterface $notifierInterface
* #param LoggerInterface $logger
* #SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
ResourceConnection $resourceConnection,
OrderRepositoryInterface $orderRepository,
InvoiceDocumentFactory $invoiceDocumentFactory,
PaymentAdapterInterface $paymentAdapter,
OrderStateResolverInterface $orderStateResolver,
OrderConfig $config,
InvoiceRepository $invoiceRepository,
InvoiceOrderValidator $invoiceOrderValidator,
NotifierInterface $notifierInterface,
LoggerInterface $logger
) {
$this->resourceConnection = $resourceConnection;
$this->orderRepository = $orderRepository;
$this->invoiceDocumentFactory = $invoiceDocumentFactory;
$this->paymentAdapter = $paymentAdapter;
$this->orderStateResolver = $orderStateResolver;
$this->config = $config;
$this->invoiceRepository = $invoiceRepository;
$this->invoiceOrderValidator = $invoiceOrderValidator;
$this->notifierInterface = $notifierInterface;
$this->logger = $logger;
}
/**
* #param int $orderId
* #param bool $capture
* #param array $items
* #param bool $notify
* #param bool $appendComment
* #param \Magento\Sales\Api\Data\InvoiceCommentCreationInterface|null $comment
* #param \Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface|null $arguments
* #return int
* #throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
* #throws \Magento\Sales\Api\Exception\CouldNotInvoiceExceptionInterface
* #throws \Magento\Framework\Exception\InputException
* #throws \Magento\Framework\Exception\NoSuchEntityException
* #throws \DomainException
*/
public function execute(
$orderId,
$capture = false,
array $items = [],
$notify = false,
$appendComment = false,
InvoiceCommentCreationInterface $comment = null,
InvoiceCreationArgumentsInterface $arguments = null
) {
$connection = $this->resourceConnection->getConnection('sales');
$order = $this->orderRepository->get($orderId);
$invoice = $this->invoiceDocumentFactory->create(
$order,
$items,
$comment,
($appendComment && $notify),
$arguments
);
$errorMessages = $this->invoiceOrderValidator->validate(
$order,
$invoice,
$capture,
$items,
$notify,
$appendComment,
$comment,
$arguments
);
if ($errorMessages->hasMessages()) {
throw new \Magento\Sales\Exception\DocumentValidationException(
__("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages->getMessages()))
);
}
$connection->beginTransaction();
try {
$order = $this->paymentAdapter->pay($order, $invoice, $capture);
$order->setState(
$this->orderStateResolver->getStateForOrder($order, [OrderStateResolverInterface::IN_PROGRESS])
);
$order->setStatus($this->config->getStateDefaultStatus($order->getState()));
$invoice->setState(\Magento\Sales\Model\Order\Invoice::STATE_PAID);
$this->invoiceRepository->save($invoice);
$this->orderRepository->save($order);
$connection->commit();
} catch (\Exception $e) {
$this->logger->critical($e);
$connection->rollBack();
throw new \Magento\Sales\Exception\CouldNotInvoiceException(
__('Could not save an invoice, see error log for details')
);
}
if ($notify) {
if (!$appendComment) {
$comment = null;
}
//$this->notifierInterface->notify($order, $invoice, $comment);
}
return $invoice->getEntityId();
}
}
Now all you have to do is setup events.xml and observe sales_order_shipment_save_after
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name='sales_order_shipment_save_after'>
<observer name='SendInvoiceWithShipment' instance='Vendor\Module\Observer\SendInvoiceWithShipment'
/>
</event>
</config>
Observer leverages standard Magento 2 transactional email $this->_invoiceSender->send($invoice); like so:
<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
class SendInvoiceWithShipment implements ObserverInterface
{
protected $_invoiceSender;
public function __construct(
InvoiceSender $invoiceSender
) {
$this->_invoiceSender = $invoiceSender;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$order = $observer->getShipment()->getOrder();
if (!$order) {
// Dont send invoice if order is not provided
return;
}
$invoices = $order->getInvoiceCollection();
foreach ($invoices as $invoice) {
try {
$this->_invoiceSender->send($invoice);
} catch (\Exception $e) {
// Do something if failed to send
}
}
}
}

Handle filesUpload in a single table Symfony

Thank you for your interest,
SHORT
I want to manage all my uploads (Image, PDF, Video etc...) in a single entity, so I use entity Inheritance to get various "types" and OneToOne relations to link parent entity with correct upload. I didn't found any bundle to do this and face problems:
Constraints use
Setting uploaded file and not upload entity
Get uploaded file and not upload entity (edition)
LONG
Instead of having 1 file management in each table (which is quiet verbose) I preferred to have only one table Uploads to handle every Uploads. Then I just have to do OneToOne relations to get my file, plus using inheritance I can apply various treatment depending on Image or PDF for example.
I have at least 4 entities that needs image, so I think that 1to1 relation is a good choice.
But I face problems doing things like this :
Constraints aren't taking into account
Edition of $file should set $file->file (it doesn't send the entity from Uploads/Image but the file to create this entity
The Uploaded file isn't loaded on entity edition and should be reuploaded each time I edit entity
Does anyone did this ? I can't find out how to achieve this correctly.
Looking at the assert problem I tried to:
Define asserts on Image (this doesn't work as expected as the form target the $file of WithImage)
Using annotation #Assert\Image()
Using loadValidatorMetadata
Using annotation #Assert\Callback()
Define assert on form field 'constraints' => array(new Assert\Image()), this works but need to be defined everywhere I use it...
Looking at the setter misused I found a workaround, but this is quiet ugly:
public function setFile($file = null)
{
if ($file instanceof \Symfony\Component\HttpFoundation\File\UploadedFile) {
$tmpfile = new Image();
$tmpfile->setFile($file);
$file = $tmpfile;
}
$this->file = $file;
return $this;
}
(PS: I read about traits to avoid copy/paste of code, I have checked the SonataMediaBundle but this doesn't seems to apply to my case)
CODE
So I designed my classes as follow:
Entity\Uploads.php To handle all the life of a file from upload to remove (and access, move, edit, possibly thumbnail etc ...)
<?php
namespace Acme\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Acme\CoreBundle\Utils\UUID;
/**
* Uploads
*
* #ORM\Table(name="uploads")
* #ORM\Entity(repositoryClass="Acme\CoreBundle\Repository\UploadsRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="class", type="string")
* #ORM\DiscriminatorMap({"image" = "Image"})
* #ORM\HasLifecycleCallbacks
*/
abstract class Uploads
{
protected $file;
private $tempFileName;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* #var string
*
* #ORM\Column(name="fileName", type="string", length=36, unique=true)
*/
private $fileName; // UUID
/**
* #var string
*
* #ORM\Column(name="extension", type="string", length=4)
*/
private $extension;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set date.
*
* #param \DateTime $date
*
* #return uploads
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date.
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set fileName.
*
* #param string $fileName
*
* #return uploads
*/
public function setFileName($fileName)
{
$this->fileName = $fileName;
return $this;
}
/**
* Get fileName.
*
* #return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Set extension
*
* #param string $extension
*
* #return string
*/
public function setExtension($extension)
{
$this->extension = $extension;
return $this;
}
/**
* Get extension
*
* #return string
*/
public function getExtension()
{
return $this->extension;
}
public function getFileNameExt()
{
return $this->getFileName().'.'.$this->getExtension();
}
public function setFile(UploadedFile $file)
{
$this->file = $file;
if (null !== $this->getId()) {
$this->tempFileName = $this->getFileNameExt();
$this->fileName = null;
$this->extension = null;
}
}
public function getFile()
{
return $this->file;
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpload()
{
if (null === $this->file) {
return;
}
$this->extension = $this->file->guessExtension();
$this->fileName = UUID::v4();
$this->preUpdateFile();
}
protected function preUpdateFile(){} // To define if specific treatment
/**
* #ORM\PrePersist()
*/
public function prePersistDate()
{
$this->date = new \DateTime();
return $this;
}
/**
* #ORM\PostPersist()
* #ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
if (null !== $this->tempFileName) {
$oldFile = $this->getUploadRootDir().$this->tempFileName;
if (file_exists($oldFile)) {
unlink($oldFile);
}
}
$this->file = $this->file->move(
$this->getUploadRootDir(),
$this->getFileNameExt()
);
$this->postUpdateFile();
}
protected function postUpdateFile(){} // To define if specific treatment
/**
* #ORM\PreRemove()
*/
public function preRemoveUpload()
{
// On sauvegarde temporairement le nom du fichier
$this->tempFileName = $this->getFileNameExt();
$this->preRemoveFile();
}
protected function preRemoveFile(){} // To define if specific treatment
/**
* #ORM\PostRemove()
*/
public function removeUpload()
{
$oldFile = $this->getUploadRootDir().$this->tempFileName;
if (file_exists($oldFile)) {
unlink($oldFile);
}
$this->postRemoveFile();
}
protected function postRemoveFile(){} // To define if specific treatment
public function getFileUri()
{
return $this->getUploadDir().$this->getFileNameExt();
}
public function getUploadDir()
{
return 'uploads/';
}
protected function getUploadRootDir()
{
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
public function __toString() {
return $this->getFileNameExt();
}
}
Entity\Image.php A specific type of upload with its own constraints and file management
<?php
namespace Acme\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Image
*
* #ORM\Entity(repositoryClass="Acme\CoreBundle\Repository\ImageRepository")
*/
class Image extends Uploads
{
}
Entity\WithImage.php An entity which needs an Image
<?php
namespace Acme\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* WithImage
*
* #ORM\Table(name="with_image")
* #ORM\Entity(repositoryClass="Acme\CoreBundle\Repository\WithImageRepository")
*/
class WithImage
{
/**
* #ORM\OneToOne(targetEntity="Acme\CoreBundle\Entity\Image", cascade={"persist", "remove"})
*/
protected $file;
}
Some thoughts come to my mind to help you achieve what you want.
First, you have to upload the files in a form, and the constraints should be in a property in an entity (unless you want to have the pain of writing your constraints in every form, which is not very mantainable). So, for every entity that's going to have files, define a file property (not ORM anotated) and write your constraints there. Also add the respective getters and setters.
/**
* #var UploadedFile
* #Assert\NotBlank(groups={"New"})
* #Assert\File(mimeTypes={"text/html", "text/markdown", "text/plain"})
*/
private $file;
Second, you might ask ¿but how do I save them to a different Entity? This is when I would recommend you to use a Doctrine Event Subscriber. Basically, is a service that is defined with a doctrine.event_subscriber tag which class implements the Doctrine\Common\EventSubscriber Interface. You can subscribe to events like preUpdate, postLoad, and the interesting for you: prePersist.
My take on this would be that you subscribe to the prePersist event. The event will pass you the entity (with that file non-orm property we created, that has the UploadedFile instance holding your file info).
Then, using the info for that file, create a new Upload entity, pass all the info you want, and then set that in the real file orm mapped property that holds your file relationship with your desired entity. For this to work you will have to enable persist cascade if I recall correctly.
The benefits of this:
1. You can define your constraints in your Entities.
2. You can have the Uploads Entity you desire.
The only major problem is that you will have to do all the retrieval, storing and updating of the Uploads entity through a listener. But's the only thing I can think of to help you.

hydrate multiple objects zf2

I need to hyrdate multiple objests in one form. Here is what I use:
Product Form - I have a form where I call three fieldsets
Product Fieldset
Promotion Fieldset
Category Fieldset
I have Models for all the necessary tables, here is an example for the product model:
class Product implements ProductInterface
{
/**
* #var int
*/
protected $Id;
/**
* #var string
*/
protected $Title;
/**
* #var float
*/
protected $Price;
/**
* #var string
*/
protected $Description;
/**
* #var string
*/
protected $Url;
/**
* #var \DateTime
*/
protected $DateAdded;
/**
* #var string
*/
protected $Image;
/**
* #var int
*/
protected $Status;
/**
* #return int
*/
public function getId()
{
return $this->Id;
}
/**
* #param int $Id
*/
public function setId($Id)
{
$this->Id = $Id;
}
/**
* #return string
*/
public function getTitle()
{
return $this->Title;
}
/**
* #param string $Title
*/
public function setTitle($Title)
{
$this->Title = $Title;
}
/**
* #return float
*/
public function getPrice()
{
return $this->Price;
}
/**
* #param float $Price
*/
public function setPrice($Price)
{
$this->Price = $Price;
}
/**
* #return string
*/
public function getDescription()
{
return $this->Description;
}
/**
* #param string $Description
*/
public function setDescription($Description)
{
$this->Description = $Description;
}
/**
* #return string
*/
public function getUrl()
{
return $this->Url;
}
/**
* #param string $Url
*/
public function setUrl($Url)
{
$this->Url = $Url;
}
/**
* #return \DateTime
*/
public function getDateAdded()
{
return $this->DateAdded;
}
/**
* #param \DateTime $DateAdded
*/
public function setDateAdded($DateAdded)
{
$this->DateAdded = $DateAdded;
}
/**
* #return string
*/
public function getImage()
{
return $this->Image;
}
/**
* #param string $Image
*/
public function setImage($Image)
{
$this->Image = $Image;
}
/**
* #return int
*/
public function getStatus()
{
return $this->Status;
}
/**
* #param int $Status
*/
public function setStatus($Status)
{
$this->Status = $Status;
}
In my controllers I want to bind the data to my view so I can edit them.
try {
$aProduct = $this->productService->findProduct($iId);
} catch (\Exception $ex) {
// ...
}
$form = new ProductForm();
$form->bind($aProduct);
In the first place I need to select all the necessary information from the DB. I join three tables product, promotion and category tables. I must return the data to my controller as objects and bind them in my form to be able to edit on the view page.
Please give me some ideas how to accomplish this so I can continue with my development. I am stuck.
I will appreciate all the links which can help me or give me any ideas/examples from the real life.
public function findProduct($Id)
{
$iId = (int) $Id;
$sql = new Sql($this->dbAdapter);
$select = $sql->select('product');
$select->join('promotion', 'promotion.ProductId = product.Id', array('Discount', 'StartDate', 'EndDate', 'PromotionDescription' => 'Description', 'PromotionStatus', 'Type'), 'left');
$select->join('producttocategory', 'producttocategory.ProductId = product.Id', array('CategoryId'), 'left');
$select->join('category', 'category.Id = producttocategory.CategoryId', array('ParentId', 'Title', 'Description', 'Url', 'DateAdded', 'Image', 'Status'), 'left');
$where = new Where();
$where->equalTo('product.Id', $iId);
$select->where($where);
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute();
if ($result instanceof ResultInterface && $result->isQueryResult()) {
$resultSet = new HydratingResultSet($this->hydrator, $this->productPrototype);
return $resultSet->initialize($result);
}
throw new \Exception("Could not find row $Id");
}
I need to hydrate the result and return an object which I will use in the controller to bind the form.
You can to fill entities from a database manually.
If you want to fill automatically need to create a map between a database and entities. I made a library for making a map between DB and entities use annotations in entities https://github.com/newage/annotations.
Next step.
When you get different data from tables. Example:
SELECT
table1.id AS table1.id,
table1.title AS table1.title,
table2.id AS table2.id,
table2.alias AS table2.alias
FROM table1
JOIN table2 ON table1.id = table2.id
Need do foreach by rows and set data to entities comparing row with table name and Entity from a generated map.
Auto generating tree of entities from DB is my next project.
But it's do not finished. https://github.com/newage/zf2-simple-orm.

Symfony2 && mongodb simple reference

he guys,
i want to make a simple reference on mongodb documents using symfony2.
i have this two documents and want to store picture references into the requests document. it works for me, if i have only the picture ids in the requests document.
so i need the follow:
can everyone change the document files and make and extends the custum call to get all pictures as object from the requests (picture array)?
my original files:
Document Pictures:
<?php
namespace TestBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(repositoryClass="TestBundle\Repository\RequestsRepository")
*/
class Requests
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $title;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
Document Pictures:
<?php
namespace TestBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(repositoryClass="TestBundle\Repository\PicturesRepository")
*/
class Pictures
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $filename;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setFilename($filename)
{
$this->filename = $filename;
}
public function getTitle()
{
return $this->filename;
}
}
My Basic Calls:
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm->getRepository('TestBundle:Requests')->find($requestId);
To my tests:
i added in the requests document the follow:
/**
* #MongoDB\ReferenceMany(targetDocument="Pictures",cascade={"persist"},simple="true")
*/
protected $pictures = array();
public function setPictures($pictures)
{
$this->pictures[] = $pictures;
}
public function getPictures()
{
return $this->pictures;
}
and added pictures like this:
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$photo = $dm->getRepository('TestBundle:Pictures')->find($photoId);
$dm1 = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm1->getRepository('TestBundle:Requests')->find($requestId);
$request->setPictures($photo);
$dm1->flush();
this works - but i cannot get the pictures by loading the document.
my code to load:
$dm1 = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm1->getRepository('TestBundle:Requests')->find($requestId);
$pictures = $request->getPictures();
foreach($pictures as $picture)
{
print $picture->getId();
}
THIS WILL NOT WORK. i become the follow error:
Fatal error: Doctrine\ODM\MongoDB\Proxy\ProxyFactory::getProxy():
Failed opening required
'.../app/cache/dev/doctrine/odm/mongodb/Proxies/_CG_TestBundleDocumentPictures.php'
(include_path='.:.../library:/usr/local/zend/share/pear') in
..../test/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Proxy/ProxyFactory.php
on line 100
thanks, jan
First off you only need to call doctrine one time in $dm your overloading your resources and thats bad practice. One function, one Doctrine call. Secondly, you need a $dm->persist($request) and then $dm->flush(). Create a OnetoOne between your Documents and then make $pictures an Doctrine Array Collection. Then set a picture like you tried, then make a smiple query and call $request->getPicture()->getId().
Ok i found the error:
In the deps file i have the following lines:
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.1.4
[doctrine-dbal]
git=http://github.com/doctrine/dbal.git
version=2.1.7
[doctrine]
git=http://github.com/doctrine/doctrine2.git
version=2.1.7
After updating them to:
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.2.1
[doctrine-dbal]
git=http://github.com/doctrine/dbal.git
version=2.2.1
[doctrine]
git=http://github.com/doctrine/doctrine2.git
version=2.2.1
And doing php bin/vendors update the references will work again