Get scale unit at cart - symfony

I need the scale unit at my cart to show it at the frontend, but I do not get it.
I tried by a subscriber and to load the product, but I do not get the selected scale unit.
public function onLoadCart(OffcanvasCartPageLoadedEvent $event)
{
foreach ($event->getPage()->getCart()->getLineItems() as $item) {
$product = $this->productRepository->search(
new Criteria(
[
$item->getId()
]
),
$event->getContext()
)->first();
dd($product);
}
}

The term scale unit offset me a little at first. I assume you are looking for the ProductUnit. The ProductUnit is an association, and you need to add this to your criteria.
public function onLoadCart(OffcanvasCartPageLoadedEvent $event)
{
foreach ($event->getPage()->getCart()->getLineItems() as $item) {
$criteria = new Criteria(
[
$item->getId()
]
);
$criteria->addAssociation('unit');
$product = $this->productRepository->search(
$criteria,
$event->getContext()
)->first();
dd($product);
}
}

Related

Get woocommerce parent product name only

I'm using this function to get the product name and return it in a short code:
public function getProducts() {
$items = $this->order->get_items();
$product = chr(10);
if(!empty($items)) {
foreach ($items as $item) {
$product_item = $item->get_product();
if ($product_item) {
$product = $item['name'];
}
}
}
$return['{products}'] = $product;
in case of product with variations, I get:
parent name - variation name (eg: shirt - black)
but I'd like to get only the parent name.
How can I do to solve it?
You should test if the product is a variation, and if so, get the parent product. Then you can get the name.
if ($product_item->is_type('variable')) {
$parent_product = wc_get_product($product_item->get_parent_id());
$product = $parent_product->get_name();
}
This should return the product name:
$product_item->get_name();

Magento 2 get product collection by price range

How can I create a production collection based on pricerange in Magento 2.
This is what i have so far:
<?php namespace Qxs\Related\Block;
class Related extends \Magento\Framework\View\Element\Template
{
protected $_productCollectionFactory;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
\Magento\Catalog\Model\Product\Visibility $productVisibility,
array $data = []
)
{
$this->_productCollectionFactory = $productCollectionFactory;
$this->productStatus = $productStatus;
$this->productVisibility = $productVisibility;
parent::__construct($context, $data);
}
public function getProductCollection()
{
//var_dump($this->currentProduct());
$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToSelect('*')
->addAttributeToFilter('special_price', ['from' => 0, 'to' => 1000])
->addAttributeToFilter('status', ['in' => $this->productStatus->getVisibleStatusIds()])
->setVisibility($this->productVisibility->getVisibleInSiteIds())
->setPageSize(5);
return $collection;
}
public function currentProduct()
{
return $this->_coreRegistry->registry('product');
}
}
?>
However, the code does not return a result including a price range. The result is totally empty but should return some products, how can I filter on price-range?
Thanks,
Range filters, to me work in this way, with addFieldToFilter. Have you tried it?
$orders = $this->_orderCollectionFactory->create()
->addAttributeToSelect('*')
->addFieldToFilter( 'created_at' , array('from' => $dateFrom, 'to' => $dateTo) )
->setOrder('created_at', 'desc' );
->setPageSize(200);

Validation on extended fields UserDefinedForm

I have made an extension on the UserDefinedForm (module userforms). This works well, but I cannot figure out how to set validation on this extra fields. This is (a part of) my code:
class UserDefinedPaymentForm_Controller extends UserDefinedForm_Controller {
private static $allowed_actions = array(
"finished",
"complete",
"error"
);
public function getFormFields() {
//Payment fields
$supported_methods = PaymentProcessor::get_supported_methods();
$gateways = array();
foreach ($supported_methods as $methodName) {
$methodConfig = PaymentFactory::get_factory_config($methodName);
$gateways[$methodName] = $methodConfig['title'];
}
$fields = parent::getFormFields();
$fields->add(new NumericField("PaymentAmount", _t('UserDefinedPaymentForm.PAYMENT_AMOUNT', 'Payment Amount')));
$fields->add(new Literalfield("literalfield", _t('UserDefinedPaymentForm.PAY', '<h2>Pay</h2>')));
$fields->add(new Literalfield("literalfield", _t('UserDefinedPaymentForm.PAY_INSTRUCTIONS', '<p>Choose your prefered payment method and click Pay:</p>')));
$fields->add(new DropdownField("PaymentMethod", _t('UserDefinedPaymentForm.PAYMENT_METHOD', 'Payment Method'), $gateways));
return $fields;
}
}
Now I want to validate the field PaymentAmount, the value of this field has to be 2 or more. How can I do this?
I would guess (I haven't tested this) your best bet is to create a subclass of UserFormValidator and override the php($data) method.
Then, in your UserDefinedPaymentForm_Controller, you will also need to override the Form method.
class PaymentAmountUserFormValidator extends UserFormValidator {
public function php($data) {
$result = parent::php($data);
if ($result === true) {
// verify your PaymentAmount here and return true or false, accordingly
}
return $result;
}
class UserDefinedPaymentForm_Controller {
...
public function Form()
{
$form = UserForm::create($this);
// Generate required field validator
$requiredNames = $this
->getController()
->Fields()
->filter('Required', true)
->column('Name');
$validator = new PaymentAmountUserFormValidator($requiredNames);
$form->setValidator($validator);
$this->generateConditionalJavascript();
return $form;
}
...
}

Set order for posted collection entities

I have two entities, the scale and scale elements. These are available in a OneToMany relationship. The scale elements have an attribute called "sorting". In this column, I will save the order.
Also i create a form ScaleType with collection ScaleElements. I can sort the scale elements with jquery sortable and post the sorted elements. After i post the form i will get the scale elements in posted order to save the "sorting" column.
My edit action which handle this issue looks like:
public function editAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$scale = $em->getRepository('AppMyBundle:Scale')->find($id);
if (!$scale) {
$this->get('session')->getFlashBag()->add('danger', $this->get('translator')->trans('not found'));
return $this->redirect($this->generateUrl('scale_list'));
}
// Create an ArrayCollection of the current Scaleitems objects in the database
$originalScaleElements = new ArrayCollection();
foreach ($scale->getElements() as $element) {
$originalScaleElements->add($element);
}
$form = $this->createForm($this->get('form.type.scale'), $scale);
$form->handleRequest($request);
if ($form->isValid()) {
// remove the relationship between the scale and the elements
foreach ($originalScaleElements as $element) {
if (false === $scale->getElements()->contains($element)) {
$element->setScale(null);
$em->persist($element);
$em->remove($element);
}
}
// Get elements
$scaleElements = $scale->getElements();
// Init counter
$counter = 1;
foreach ($scaleElements as $element) {
$element->setSorting($itemCounter);
$element->setScale($scale);
$em->persist($element);
$counter++;
}
$em->persist($scale);
$em->flush();
$this->get('session')->getFlashBag()->add('info', $this->get('translator')->trans('object edited', array()));
return $this->redirect($this->generateUrl('scale_list'));
}
return $this->render('AppMyBundle:Scale:edit.html.twig', array("form" => $form->createView()));
}
But the sorting attribute do not change from scale elements. It have the initial state which was set in the add action. In add action exists the same loop which set the sorting attribute for posted scale elements.
How can i solve this issue?

Symfony2 / Typecasting query results to simpeler object

I am using Stof's DoctrineExtension bundle to retrieve my Tree, now I want to convert that tree to an array (which will then in turn get converted to json).
The format of NestedTreeRepository->childrenHierarchy() is not in the correct format though, I want to modify the output so only the node "title" property and the "id" property is returned, and put any children in a "children" subarray. In compliance with this format (JSON):
{
label: 'node1',
children: [
{ label: 'child1' },
{ label: 'child2' }
]
},
{
label: 'node2',
children: [
{ label: 'child3' }
]
}
}
I have tried to following code, this returns the same as childrenHierarchy() but would allow me to modify the query.
$query = $em
->createQueryBuilder()
->select('node')
->from('MyBundle:Page', 'node')
->orderBy('node.root, node.lft', 'ASC')
->getQuery()
;
$nodes = $query->getArrayResult();
[Do magic here]
$tree = $pagerepo->buildTree($nodes);
Is it possible to typecast every node into a much simpler object containing only the following property's:
id
title
a few other ints used for positioning
if I would then run that through json_encode() I would have exactly what I needed.
Any other solutions are of course welcome.
my code for this purpose (just made this a few hours ago)
it's a remake of stof's buildTreeArray function
in the controller (I'm writing this for symfony2):
function gettreeAction {
$query = .... // do your query
$tree = $this->buildTree($query->getArrayResult());
$response = new Response(json_encode($tree));
return $response;
}
private function buildTree($nodes)
{
$nestedTree = array();
$l = 0;
if (count($nodes) > 0) {
// Node Stack. Used to help building the hierarchy
$stack = array();
foreach ($nodes as $child) {
$item = array();
$item['name'] = $child['title'];
$item['id'] = 'page_'.$child['id'];
$item['level'] = $child['level'];
$item['children'] = array();
// Number of stack items
$l = count($stack);
// Check if we're dealing with different levels
while($l > 0 && $stack[$l - 1]['level'] >= $item['level']) {
array_pop($stack);
$l--;
}
// Stack is empty (we are inspecting the root)
if ($l == 0) {
// Assigning the root child
$i = count($nestedTree);
$nestedTree[$i] = $item;
$stack[] = &$nestedTree[$i];
} else {
// Add child to parent
$i = count($stack[$l - 1]['children']);
$stack[$l - 1]['children'][$i] = $item;
$stack[] = &$stack[$l - 1]['children'][$i];
}
}
}
return $nestedTree;
}
works perfectly with jqTree...
I have solved it as following:
public function getPageTreeAction() {
$pagerepo = $this->getDoctrine()->getRepository('MyBundle:Page');
$em = $this->getDoctrine()->getEntityManager();
$query = $em
->createQueryBuilder()
->select('node')
->from('MyCorpBundle:Page', 'node')
->orderBy('node.root, node.lft', 'ASC')
->getQuery();
$flatnodearray = $query->getArrayResult();
$flatsimplenodearray = array();
foreach ($flatnodearray as $currentNode) {
$currentSimpleNode = array();
$currentSimpleNode['id'] = $currentNode['id'];
$currentSimpleNode['lft'] =$currentNode['lft'];
$currentSimpleNode['rgt'] = $currentNode['rgt'];
$currentSimpleNode['lvl'] = $currentNode['lvl'];
$currentSimpleNode['title'] = $currentNode['title'];
$flatsimplenodearray[] = $currentSimpleNode;
}
$tree = $pagerepo->buildTree($flatsimplenodearray);
$response = new Response(json_encode($tree));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
I would use the Stofs Repository function to get the nodes in an hierarchical array:
$repo = $em->getRepository('MyBundle:Page');
$arrayTree = $repo->childrenHierarchy();
And I think there is no other solution than modify that array manually. After you have removed some properties that you dont need, you can json_encode the array and return it.

Resources