I get error below while trying to add item to my cart:
Darryldecode \ Cart \ Exceptions \ InvalidItemException
validation.numeric
The error comes from this part of my code:
$customAttributes = [];
if(!empty($request->attr)){
foreach($request->attr as $sub) {
// find the suboption
$sub = Suboption::find($sub);
if (!empty($sub->id)) {
$itemCondition1 = new \Darryldecode\Cart\CartCondition(array(
'name' => $sub->title,
'value' => $sub->price,
'type' => 'additional',
'target' => 'item',
));
array_push($customAttributes, $itemCondition1);
}
}
}
and it take place in here:
Cart::add(array(
'id' => $product->id,
'name' => $product->title,
'price' => $price,
'quantity' => $request->input('quantity'),
'attributes' => $weightArray,
'conditions' => $customAttributes, //here
));
The $customAttributes code supposed to get data IF product does have those information And user chose any of it and suppose to ignore if product doesn't have any of those info or user didn't chose any of it.
Issue is
The code expect data no matter what, product does have that info or not, user selected any or not, even if user select that data still i get error above.
Demo
https://imgur.com/a/KHJqp
any idea why is that?
UPDATE
I figured my issue comes from 'price' => $price, in my add method where i get my $price like:
$price = $product->discounts;
if($price->count() > 0 ) {
foreach($discounts as $disc){
if($disc->value_to >= $mytime) {
$price = $product->price - $disc->amount;
}
}
}else{
$price = $product->price;
}
this part supposed to get product price if there is no discount, and get discounted price if there is.
How I get to this line of code? here is it
SOLVED
I used hidden field and got my data from front-end instead of controller method.
Related
I`m trying to scrape with a panther, my goal to get a list of all books from given page and then go through each book and get book description, this is my code:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
use Symfony\Component\Panther\Client;
use Symfony\Component\Panther\DomCrawler\Crawler;
require_once "vendor/autoload.php";
$client = Client::createChromeClient();
$crawler = $client->get('https://books.toscrape.com/catalogue/category/books/default_15/');
$books_array = [];
$crawler->getCrawler()->filter('.row li article')->each(function (Crawler $node) use (&$books_array, $client) {
$title = $node->filter('h3 a')->count() > 0 ? $node->filter('h3 a')->text() : 'missing';
$price = $node->filter('div.product_price p')->count() > 0 ? $node->filter('div.product_price p')->text() : 'missing';
$link = $node->filter('h3 a')->attr('href');
$url = 'https://books.toscrape.com/catalogue/' . substr($link, 9);
$book_page = $client->get($url); //error appears here
$book_description = $book_page->getCrawler()->filter('.sub-header + p')->count() > 0 ? $book_page->getCrawler()->filter('.sub-header + p')->text() : 'missing';
$books_array[] = [
'title' => $title,
'current_price' => $price,
'book_description' => $book_description
];
});
but I get this error:
PHP Fatal error: Uncaught Facebook\WebDriver\Exception\StaleElementReferenceException: stale element reference: element is not attached to the page document
(Session info: headless chrome=101.0.4951.64) in /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Exception/WebDriverException.php:127
Stack trace:
#0 /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php(372): Facebook\WebDriver\Exception\WebDriverException::throwException()
#1 /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php(585): Facebook\WebDriver\Remote\HttpCommandExecutor->execute()
#2 /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Remote/RemoteExecuteMethod.php(27): Facebook\WebDriver\Remote\RemoteWebDriver->execute()
#3 /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebElement.php(130): Facebook\WebDriver\Remote\RemoteExecuteMethod->execute()
#4 /var/www/parserjs/vendor/symfony/panther/src/DomCrawler/Crawler.php(393): Facebook\WebDriver\Remote\RemoteWebElement->findElements in /var/www/parserjs/vendor/php-webdriver/webdriver/lib/Exception/WebDriverException.php on line 127
I tried to run only with the first element eq(0), then there is no error, and get an array with 1 single element, but I need to get the whole list of books
$crawler->getCrawler()->filter('.row li article')->eq(0)->each(function (Crawler $node)
I also worked with Goutte and everything was fine, but now I need to work with JS, and therefore chose the panther. (For example, see how panther works, took this site https://books.toscrape.com/).
Please help me, I understand what the problem, I have already spent a lot of time looking for a solution, and have not found an answer. Thanks!
I am using "Add a select field that will change price in Woocommerce simple products" answer code. It only uses a single selection field for filtering. I want to extend this code using jQuery to be able to use multiple fields for filtering.
Example: 2 select fields, one text, a checkbox and some radio buttons that will all determine the final calculated price.
// Select field
woocommerce_form_field('materials_pack', array(
'type' => 'select',
'class' => array('material-field form-row-wide'),
'label' => __('Select Materials:', $domain),
'required' => true,
'options' => $options,
),'');
<script>
jQuery(function($){
var a = <?php echo json_encode($prices); ?>,
b = 'p.price',
c = 'select[name="materials_pack"]';
$(c).on( 'change', function(){
$.each( a, function( key, value ){
if( $(c).val() == key )
$(b).html(value);
});
});
});
</script>
How to use it for multi fields? and how do the jquery script?
Ok i found my answer here now i just need to how to do it in this code?
add_action('woocommerce_before_calculate_totals', 'set_cutom_cart_item_price', 20, 1);
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['material_data']['new_price'] ) ){
$cart_item['data']->set_price( $cart_item['material_data']['new_price'] );
}
}
I'm trying to create a form that maps to an entity of the type "Participant". A participant is in a one-to-one relationship with a 'person'. Adding a participant, I want to first give the option to choose a person already in the database and if the right one doesn't exist, create that person with the participant form.
This works if I do it with two pages/forms. The first one trying to choose an existing person, otherwise open a new page with the different form.
First page:
$form->add('person', AjaxEntityType, [ // EntityType but with select2 ajax
'class' => Person::class,
'remote_route' => 'person_ajax_list'
]);
Second page:
$participant->setPerson(new Person());
$form->add('person', PersonType::class);
// adds PersonType fields to the Participant form
Well, that works, but it's terribly slow and unecessary. What I'd rather want is having BOTH of those shown, where the PersonType form fields (first name, last name, title, company, address, etc.) are automatically populated with the persons data, if one is selected. Otherwise, if no Person is selected and the form is submitted with data entered, a new Person should be created and persisted in the database.
It's sadly not possible to render the 'person' twice, once as a dropdown and once as a PersonType form. So how would I go about achieving what I want, without surreal amounts of JavaScript?
My current solution would be to manually create all the required fields with JavaScript and populate them with the person data I'd get with another Ajax request on a onchange event on the person dropdown, then in the PRE_SUBMIT event of the form, remove the 'person' field and add it again as a PersonType field, check if the entered data corresponds to an existing person or a new one and then act accordingly. There has to be a better solution, right?
Form events have sadly otherwise proven majorly pointless, as it's not possible to attach an event listener to a 'change' event on one of the fields.
Thanks.
Ended up solving it with an unmapped person choice field and javascript to automatically update the data (using ajax).
participant/add.twig:
{% block javascripts %}
<script type="text/javascript">
$(document).ready(function () {
function onTrainerChange() {
let trainerId = $('#participant_person_choose').val();
$.get(Routing.generate('person_data_ajax', { id: trainerId }), function (data) {
$('#participant_person_gender').val(data.gender);
$('#participant_person_title').val(data.title);
$('#participant_person_firstName').val(data.firstName);
$('#participant_person_lastName').val(data.lastName);
$('#participant_person_email').val(data.email);
$('#participant_person_telephone').val(data.telephone);
if (data.company) {
let company = $('#participant_person_company');
company.empty();
company.append(new Option(data.company.text, data.company.id));
company.val(data.company.id);
company.trigger('change');
// manipulate dom directly because of .select('data') bug with select2 >=4.0
}
});
};
let trainer = $('#participant_person_choose');
trainer.change(onTrainerChange);
});
</script>
{% endblock %}
ParticipantController add:
$participant = new Participant($seminar);
$person = $participant->getPerson() ?? new Person();
$participant->setPerson($person);
$form = $this->createParticipantForm($participant)
->add('person_choose', AjaxEntityType::class, [
'mapped' => false,
'class' => Person::class,
'remote_route' => 'person_select_ajax',
'placeholder' => 'form.personCreate',
'label' => 'form.person'
])
->add('person', PersonType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($form->get('reservation')->getData()) {
$participant->setInterested();
}
$personEntered = $form->get('person')->getData();
$personChosen = $form->get('person_choose')->getData();
if ($personChosen) {
$person = $personChosen;
$person->setGender($personEntered->getGender());
$person->setTitle($personEntered->getTitle());
$person->setFirstName($personEntered->getFirstName());
$person->setFirstName($personEntered->getLastName());
$person->setCompany($personEntered->getCompany());
$person->setEmail($personEntered->getEmail());
$person->setTelephone($personEntered->getTelephone());
$participant->setPerson($person);
}
$this->getDoctrine()->getManager()->persist($person);
$this->getDoctrine()->getManager()->persist($participant);
}
PersonController Ajax:
/**
* #Route("/{id}/data", name="person_data_ajax", methods={"GET"}, options={"expose": true})
*/
public function dataAjax(Person $person, PhoneNumberHelper $phonenumberHelper)
{
$arr = [
'id' => $person->id,
'gender' => $person->getGender(),
'title' => $person->getTitle(),
'firstName' => $person->getFirstName(),
'lastName' => $person->getLastName(),
'email' => $person->getEMail(),
'telephone' => $person->getTelephone() ? $phonenumberHelper->format($person->getTelephone(), PhoneNumberFormat::NATIONAL) : null,
'company' => $person->getCompany() ? [
'id' => $person->getCompany()->id,
'text' => $person->getCompany()->__toString()
] : null
];
return new JsonResponse($arr);
}
Hope this can help someone else. Really disappointed with how limited Symfonys Forms are.
I have a form with four fields - three of which are properly being sent up to the controller. One field is a drop-down selector field and it is not being sent. Here is sample form code from my schedule_date field which is being sent properly:
<?php
echo $this->Form->input("schedule_date"
,array('label' => false
,'type' => 'text'
,'class' => 'step_dates'
,'readOnly' => 'readOnly'
)
);
?>
And here is the code for the drop-down box which is NOT being sent properly:
<?php
echo $this->Form->input("project_step_type_id"
,array('label' => false
,'id' => 'project_step_type_id'
,'class' => 'project_step_type_id'
,'empty' => '( select step )'
,'options' => $project_step_types
)
);?>
Here is what my debug looks like on the form data I'm sending back (notice project_step_type_id is missing):
<pre class="cake-debug">
array(
'user_id' => '402',
'trainer_user_id' => '524',
'schedule_date' => '2014-11-26'
)
</pre>
Can anyone help? All fields are inside the form tag. I believe the issue is with this line:
request_data=$('#my_form input').serializeCakeArray();
It's not getting the "select" fields, only the "input" fields. Does anyone know how to fix that? Thank you.
The answer is:
request_data=$('#my_form input, #my_form select').serializeCakeArray();
I'm new to Yii framework and Javascript. Now, I'm using two dropdownlists for min_cost and max_cost. I'm using the below code to list the values in the dropdownlist.
<?php
$this->widget('ext.combobox.EJuiComboBox', array(
'model' => $model,
'attribute' => 'min_cost',
'data' => Yii::app()->params['cost_min_resales'],
'options' => array(
'onSelect' => 'cost_change(item.value);',
'allowText' => false,
),
'htmlOptions' => array('placeholder' => 'Min Cost', 'style'=>'width:70px'),
));
?>
</br>
<?php
$this->widget('ext.combobox.EJuiComboBox', array(
'model' => $model,
'attribute' => 'max_cost',
'data' =>Yii::app()->params['cost_max_resales'],
'options' => array(
'allowText' => false,
),
'htmlOptions' => array('placeholder' => 'Max Cost', 'style'=>'width:70px'),
));
?>
For this I'm using the below script:
<script>
function cost_change(price) {
var removed;
console.log("removed", removed);
select = "#SearchForm_max_cost_select";
var value = price;
console.log("value", value);
jQuery('#SearchForm_max_cost_select').prepend(removed);
var toKeep = jQuery('#SearchForm_max_cost_select option').filter(function() {
return parseInt(this.value) > parseInt(value);
});
console.log("to keep",toKeep);
removed = jQuery('#SearchForm_max_cost_select option').filter(function() {
return parseInt(this.value) < parseInt(value);
});
}
</script>
Now, I want to populate the second dropdownlist with values greater than the value selected in first one. Suppose there are values hardcoded in an array as (1,2,3,4,5) I select 2 from first dropdownlist then all values greater than 2 (i.e 3,4,5) should be listed in second dropdownlist.
The above script works fine. I can see the values of second dropdownlist printed in the logs . But, I'm not able to pass this values to second dropdownlist. How can I do this.
Edit :
Below is the image of the object I'm getting when I select value .
this will work, actually i was also facing the same problem but somehow figured it out.
In your controller just check for this condition..
if ($model->"yourdbid" == null) {
$model->"yourdbid" = $_POST['yourdbid'];
}