I have Eloquent Event model, which is related towards multiple dates like this:
$event->dates // shows Collection of 8 Eloquent date models
After that i need to pick the only date, what is closest to current time. I know how to do this using query of raw SQL, or DB class. But isnt there any better solution? I dont want to jump into database for data, I already have.
Date format in eloquent models is surprisingly string.
You can use what we call in laravel mutators like this ->
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
public function dates()
{
return $this->hasMany('Date');
}
/**
* Get Dates for the event.
*
* #param string $value
* #return array
*/
public function getDates()
{
$dates = $this->dates()->getQuery()->orderBy('created_at', 'asc')->get();
return $dates;
}
}
Hope this helps.
UPDATE
I think now you can also directly do this in the model definition like this -
return $this->hasMany('Date')->orderBy('created_at', 'asc')
Related
in a extbase extension i us sys_category. In list action there is no problem, all categories work as expected. But i want to write category entries with a custom database finisher from tx_form.
In the model all seems correct:
/**
* Sets the categories
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $categories
* #return void
*/
public function setCategories($categories)
{
$this->categories = $categories;
}
in my finisher:
$newAddress->setCategories($newCat);
$this->addressRepository->add($newAddress);
The form gives me only the uid of the category but for "setCategories" i need an \TYPO3\CMS\Extbase\Persistence\ObjectStorage.
How do i get a \TYPO3\CMS\Extbase\Persistence\ObjectStorage from the uid of the category?
Thanks!
You need a setter method for the categories like this:
public function addCategory($category)
{
$this->categories->attach($category);
}
This method will add one model to your object storage.
As you need the category model to be added, you need to get the corresponding model of the uid with $categoryRepository->findByUid($uid);
We are developing API with Silex and Doctrine (ODM) and we have object Story, which have property images.
class Story extends AbstractDocument
{
/** #MongoDB\Id */
protected $id;
/**
* #MongoDB\ReferenceMany(
* targetDocument="MyNamespace\Documents\Image",
* storeAs="DBRef"
* )
*/
protected $images = [];
// Other properties and methods
}
We have get method in repository (in AbstractRepository, from which extends all other repositories).
public function get(string $documentId) : array
{
$document = $this->createQueryBuilder()
->field('id')->equals($documentId)
->hydrate(false)
->getQuery()
->toArray();
}
This method returns embedded and referenced objects, but for referenceMany returns only ids without data.
Is it possible to deny lazy loading to get all documents ?
One possible solution, which we found - rewrite method toArray.
As soon as you use ->hydrate(false) you are instructing ODM to get out of your way and return you raw data from MongoDB. You are seeing the referenceMany as an array of ids because that is the raw representation, no lazy loading is involved.
The cleanest way to solve your issue would be implementing StoryRepository which would fire an additional query to get referenced images:
public function get(string $documentId) : array
{
$document = $this->createQueryBuilder()
->field('id')->equals($documentId)
->hydrate(false)
->getQuery()
->toArray();
$document['images'] = /* ... */;
return $document;
}
Magento 2: Get Product Stock Quantity and Other Stock Information
How to get the product stock quantity and information in magento 2
If we look at the StockItemRepository class the get method wants parameter $stockItemId, not $productId. Reference:
https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php#L202
I've seen many sites where stock item id IS NOT the same as product id and we should not assume it's the same ID.
To get this working you could use \Magento\CatalogInventory\Model\Stock\Item class instead and load the model by product_id field instead. I am also aware of the website_id and stock_id fields, but as far as I know it's not used (yet) and also existed in M1.
It should look something like this (code not tested):
<?php
namespace Vendor\Module\Model;
use \Magento\CatalogInventory\Model\Stock\Item;
class Mymodel
{
/**
* #var Item
*/
protected $stockItem;
/**
* Mymodel constructor.
*
* #param Item $stockItem
*/
public function __construct(Item $stockItem)
{
$this->stockItem = $stockItem;
}
/**
* Description
*
* #param $productModel
*/
public function getStockQtyByProductId($productModel)
{
try {
$stockItem = $this->stockItem->load($productModel->getId(), 'product_id');
return $stockItem->getQty();
} catch (\Exception $e) {
echo 'Something went wrong and was not handled: ' . $e->getMessage();
exit;
}
}
}
if you have product object then just use following:
echo $_product->getExtensionAttributes()->getStockItem()->getQty();
conplete object can be find as follow:
var_dump($_product->getExtensionAttributes()->getStockItem()->getData());
Actually this operation should be performed using \Magento\CatalogInventory\Api\StockRegistryInterface and here we can obtain \Magento\CatalogInventory\Api\Data\StockItemInterface, by product id or sku and we can use bunch of usefull methods to get stock information - linked product. For general stock information I recommend explore other service contracts declared in Magento\CatalogInventory\Api
Example of usage:
<?php
namespace Test\Test\Model;
class Test
{
protected $_stockRegistry;
public function __construct(\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry)
{
$this->_stockRegistry = $stockRegistry;
}
public function getStockItem($productId)
{
return $this->_stockRegistry->getStockItem($productId);
}
}
this code help you to get product quantity
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
echo $StockState->getStockQty($productId);
?>
If you have the product object and do not want to use the other classes, You can try in the following way.
// For phtml file
$prodObj = $_product->load($_product->getId()); // $_product object in list.phtml
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();
// For php class file
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();
Credits:
https://github.com/magento/magento2/issues/7057#issuecomment-256052729
Actually \Magento\CatalogInventory\Api\Data\StockStatusInterface
should answer to all your questions.
Long story short:
Magento has StockItem entity which represents amount (Qty) of specific product (productId) on a concrete stock (stockId).
StockItemInterface should be used when you would like to "write" data into the data storage (like update amount of products to sync up Magento with your ERP system or to make deduction of stock during the checkout process).
StockStatusInterface is opposite to it. It should be used to "read" data for representation (on front-end). Consider StockStatus as an index which contains aggregated stock data for each specific product.
So, if you would like to get product stock status (in stock, out of stock) by product_id.
You need using StockStatusRepositoryInterface::getList(StockStatusCriteriaInterface $searchCriteria);
get StockStatus entity for specified product
/** #var \Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory **/
$criteria = $stockStatusCriteriaFactory->create();
$criteria->setProductsFilter($productId);
/** #var \Magento\CatalogInventory\Api\Data\StockStatusRepositoryInterface $stockStatusRepository **/
$result = $stockStatusRepository->getList($criteria);
$stockStatus = current($result->getItems());
$stockStatus->getProductId(); // product id
$stockStatus->getQty(); // quantity of specified product
$stockStatus->getStockStatus(); // Could be
// Magento\CatalogInventory\Model\Stock\Status::STATUS_OUT_OF_STOCK = 0;
// or
// Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK = 1;
I have an entity Calendar with dateFrom and dateTo properties.
Now in my form I have one hidden input with date formatted like this: 2010-01-01,2011-01-01.
How can I write a data transformer in Symfony2 which will allow me to transform this date to TWO properties?
I think that the transformer himself has nothing to do with the "properties", it just handle transformation from a data structure to another data structure. You just have to handle the new data structure on your code base.
The transformer himself might look like thisĀ :
class DateRangeArrayToDateRangeStringTransformer implements DataTransformerInterface
{
/**
* Transforms an array of \DateTime instances to a string of dates.
*
* #param array|null $dates
* #return string
*/
public function transform($dates)
{
if (null === $dates) {
return '';
}
$datesStr = $dates['from']->format('Y-m-d').','.$dates['to']->format('Y-m-d');
return $datesStr;
}
/**
* Transforms a string of dates to an array of \DateTime instances.
*
* #param string $datesStr
* #return array
*/
public function reverseTransform($datesStr)
{
$dates = array();
$datesStrParts = explode(',', $datesStr);
return array(
'from' => new \DateTime($datesStrParts[1]),
'to' => new \DateTime($datesStrParts[2])
);
}
}
You can use the explode function like that :
$dates = explode(",", "2010-01-01,2011-01-01");
echo $dates[0]; // 2010-01-01
echo $dates[1]; // 2011-01-01
Then create two new DateTime.
If it's possible, use 2 hidden fields. Then use a DateTime to String datatransformer on each field. Then your form is logically mapped to your entity.
I solved a similar problem by adding a custom getter/setter to my entity (for example, getDateIntervalString and setDateIntervalString). The getter converts dateTo and dateFrom into the interval string and returns it, and the setter accepts a similarly formatted string and uses it to set dateTo and dateFrom. Then, add the field to the form like this:
$builder->add('dates', 'text', ['property_path' => 'date_interval_string'])
By overriding the property path, your custom getter and setter will be used.
i'm trying to implement this pattern http://cookbook.mongodb.org/patterns/random-attribute/ in doctrine odm.
i would like to set this attribute on the pre-persist lifecycle event. To achieve the best results, i would like to use a native javascript function Math.random() because php cannot generate random floats and i would like to avoid writing a custom function for that.
is there a way to achieve this?
i tried:
/** #PrePersist */
public function generateRandom()
{
$this->random = new \MongoCode('Math.random()');
}
but it always sets the attribute to 1, no matter the code of the function
I'm not sure that it's best solution but, it works for me:
/**
* #MongoDB\PrePersist()
* #MongoDB\PreUpdate()
*/
public function generateRandom() {
$this->random = rand();
}