I don't have any idea where is a problem. I have a router TP-link TL-WR940N and this device blocking my computer (firewall blocking IP Address) when I upload image by html form. I thought the problem are a big POST request. I modifing this code to AJAX upload file. Now i send files one by one - I send first file, waiting to complete and sending next file. My TP-Link are still blocking IP. I find 3 options in router config which genrate problem:
ICMP-FLOOD Attack Filtering
UDP-FLOOD Filtering
TCP-SYN-FLOOD Attack Filtering
Has anyone had this problem?
My actual js code:
function uploadFileAsync(idProduct, alt, iteration, files) {
var formData = new FormData();
var arrFilesLength = files.length;
var file = files[iteration];
formData.delete('fileGal[]');
formData.set('fileGal[]', file, file.name);
$.ajax({
url: documentDomain + 'admin.php?uploadFile=' + idProduct + '&imgAlt=' + alt,
type: 'POST',
async: true,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(data) {
iteration++;
if (iteration == arrFilesLength) {
$('progress').css('display', 'none');
$('.fileGal').val('');
$('.imurConvertGood').hide();
$('.productGalleryTitle').html('No file');
refreshPicturesList(idProduct);
} else {
$('progress').attr({
value: iteration,
max: arrFilesLength,
});
uploadFileAsync(idProduct, alt, iteration, files);
}
}
});
}
Upload PHP:
private function uploadFile($idProduct = null, $fi = null, $imgAlt = null) {
$config = new Config;
$idProduct = htmlspecialchars($idProduct, ENT_QUOTES);
$fi = htmlspecialchars($fi, ENT_QUOTES);
$pathFilesServer = $this->AppModel->pathFilesServer();
$productSQL = $this->AppModel->selectData('products', array('name', 'aliasID'), array('id' => $idProduct));
$productArr = $productSQL->fetch_assoc();
$aliasNameSQL = $this->AppModel->selectData('alias', 'alias', array('id' => $productArr['aliasID']));
$aliasName = $aliasNameSQL->fetch_assoc();
if (is_array($_FILES['fileGal']['name'])) {
if ($fi == null) $fi=0;
$fc = count($_FILES['fileGal']['name']);
$file_name = $_FILES['fileGal']['name'][$fi];
$file_tmp = $_FILES['fileGal']['tmp_name'][$fi];
$fi++;
} else {
$file_name = $_FILES['fileGal']['name'];
$file_tmp = $_FILES['fileGal']['tmp_name'];
}
$file_name = strtolower($file_name);
/* new name file */
$today = getdate();
$md=md5($today[0]+rand());
$tmp = explode(".", $file_name);
$extension = end($tmp);
if ($aliasName['alias'] != '') {
$newName = $aliasName['alias'].'-'.rand(1000, 9999).'.'.$extension;
} else {
$newName = $md.'.'.$extension;
}
$path = $pathFilesServer.'/Store/imgProducts/orginal/'.$newName;
$fileFromImagick = $this->helpers->resizeImage($file_tmp, 250, 250, Imagick::FILTER_LANCZOS, 1, true, null);
file_put_contents ($pathFilesServer.'/Store/imgProducts/min/'.$newName, $fileFromImagick);
$fileFromImagick = $this->helpers->resizeImage($file_tmp, 500, 500, Imagick::FILTER_LANCZOS, 1, true, null);
file_put_contents ($pathFilesServer.'/Store/imgProducts/middle/'.$newName, $fileFromImagick);
/* start upload file */
if(is_uploaded_file($file_tmp)) {
move_uploaded_file($file_tmp, $path);
}
if ($imgAlt == null) {
$this->AppModel->insertValue('pictures', array('id' => '', 'idProduct' => $idProduct, 'file' => $newName, 'alt' => $productArr['name']));
} else {
$this->AppModel->insertValue('pictures', array('id' => '', 'idProduct' => $idProduct, 'file' => $newName, 'alt' => $imgAlt));
}
if ($fi<$fc){
$this->uploadFile($idProduct, $fi);
} else {}
}
I am totaly stuck with an Ajax request. I m trying to send a response to Ajax with an encoded array to json. Ajax get a status 200 response, but only strings are sent ; not my variables.
I wonder if the probleme is due to the asynchronous... When I test with Postman, i can see the full response but Js give to me : {"recipies":[]}.
Thanks for your help.
Ajax :
searchByIngredients: function () {
console.log('Search for recipies');
var array = [];
var ingredients = $('.span-ingredient');
ingredients.each(function () {
array.push(this.innerHTML);
});
console.log(array);
console.log(Array.isArray(array));
$.ajax(
{
url: Routing.generate('shopping_list_by_ingredients_ajax'),
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(array)
}).done(function (response) {
if (null !== response) {
console.log('ok : ' + JSON.stringify(response));
console.log(typeof(response));
} else {
console.log('Error');
}
}).fail(function (jqXHR, textStatus, error) {
console.log(jqXHR);
console.log(textStatus);
console.log(error);
});
}
};
Controller :
/**
* #Route("/by-ingredient-ajax", name="shopping_list_by_ingredients_ajax", options={"expose"=true}, methods={"GET","POST"})
*
* #return JsonResponse|Response
*/
public function createShopplistByIngredientsAjax(Request $request, RecipeIngredientRepository $recipeIngredientRepository, RecipeRepository $recipeRepository)
{
if ($request->isMethod('POST')) {
$dataIngredients = json_decode($request->getContent());
$dataIngredients = $request->getContent();
// Sorry for this :/
$arrayIngredients = explode(', ', $dataIngredients);
$text = str_replace("'", '', $arrayIngredients);
$text2 = str_replace('[', '', $text);
$text3 = str_replace(']', '', $text2);
$recipiesArray = [];
// Get matching RecipeIngredient
foreach ($text3 as $data) {
/**
* #return RecipeIngredient()
*/
$recipeIngredients = $recipeIngredientRepository->findBy([
'name' => $data,
]);
foreach ($recipeIngredients as $recipeIng) {
$name = $recipeIng->getName();
$recipeNames = $recipeRepository->findRecipeByKeywwords($name);
foreach ($recipeNames as $recipeName) {
/**
* #return Recipe()
*/
$recipies = $recipeRepository->findBy([
'id' => $recipeIng->getRecipe(),
]);
// Built array with names & ids of recipies
foreach ($recipies as $key => $recipe) {
$recipeName = $recipe->getName();
$recipeId = $recipe->getId();
$recipiesArray[] = ['name' => $recipeName];
$recipiesArray[] = ['id' => $recipeId];
}
}
}
}
$response = new Response();
$response->setContent(json_encode([
'recipies' => $recipiesArray,
]));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
return new Response(
'Something wrong...',
Response::HTTP_OK,
['content-type' => 'text/html']
);
Repository :
/**
* #return Recipe[] Returns an array of Recipe objects
*/
public function findRecipeByKeywwords($value)
{
return $this->createQueryBuilder('r')
->andWhere('r.name LIKE :val')
->setParameter('val', '%'.$value.'%')
->orderBy('r.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getArrayResult();
}
composer require jms/serializer-bundle
After you have installed the package, you just need to add the bundle to your AppKernel.php file:
// in AppKernel::registerBundles()
$bundles = array(
// ...
new JMS\SerializerBundle\JMSSerializerBundle(),
// ...
);
The configured serializer is available as jms_serializer service:
$serializer = $container->get('jms_serializer');
$json=$serializer->serialize(['recipies' => $recipiesArray], 'json');
return new JsonResponse($json,200);
Symfony 2.1
$response = new Response(json_encode(array('recipies' => $recipiesArray)));
$response->headers->set('Content-Type', 'application/json');
return $response;
Symfony 2.2 and higher
You have special JsonResponse class, which serialises array to JSON:
use Symfony\Component\HttpFoundation\JsonResponse;
//
//
return new JsonResponse(array('recipies' => $recipiesArray));
https://symfony.com/doc/current/components/http_foundation.html
Before, I managed to insert an image file inside a file directory using FormData. But now, the FormData, which I am trying to use now for updating a wrong image, is returning an empty data even though I am passing the correct parameters/payload, which is the file that is an object. I tried using FormData.set for updating, and even experimenting on the forEach a bit, but none of them worked for me. In Quasar (which is like Bootstrap for Javascript), we get the rows for each data so we can update a row of data. Should I get the row for the image before the FormData finally gets a response?
Frontend
<template>
<div>
<q-table
:filter="filter"
title="Test Section"
:data="dtdata"
:columns="columns"
row-key="TestId"
>
<q-tr slot="body" slot-scope="props" :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{
col.value
}}
</q-td>
<q-td class="q-gutter-md">
<q-btn label="Edit" color="primary" #click.native="gatherData(props.row)" />
<q-btn label="Delete" color="red" #click.native="activateDel(props.row)" />
<q-btn label="Change Picture" color="green" #click.native="changeThisPic(props.row)" />
</q-td>
</q-tr>
</q-table>
</div>
</template>
<script>
methods: {
changeThisPic(row) {
this.editPic = true;
this.editData.testId = row.testId;
this.editData.testItemId = row.testItemId;
},
sendPicForUpdate() {
this.$store
.dispatch("UPDATE_PIC", {
testId: this.editData.testId,
uploadFile: this.editData.uploadFile,
testItemId: this.editData.testItemId
})
}
</script>
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
mutations: {
UPDATE_PIC ({ commit }, payload) {
const formData2 = new FormData()
Object.entries(payload).forEach(([key, val]) => {
formData2.append(key, val)
})
axios
.put('http://localhost/MyComposer/', formData2, {
params: {
updateId: 2,
testId: payload.testId,
testItemId: payload.testItemId
}
})
.then(response => {
alert(response.data)
console.log(response)
})
.catch(error => {
console.log(error)
})
}
},
Backend
<?php
if (isset($_GET['updateId']) && $_GET['updateId'] == 1) {
$data = file_get_contents('php://input');
$decoded = json_decode($data);
$testId = $decoded->{'testId'};
$sub = $decoded->{'subject'};
$question = $decoded->{'question'};
$answer = $decoded->{'answer'};
$testItem = $decoded->{'testItemId'};
$db->where('TestItemId', $testItem);
$arrayDir = array('FileLocation');
$uploaddir = $db->get('teachertest', null, $arrayDir);
$uploadfile = $uploaddir . $_FILES['uploadFile']['name'];
if (move_uploaded_file($_FILES['uploadFile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Upload failed";
}
if (!empty($sub)) {
$sdata = array(
'SubjectId' => $sub,
);
$db->where('TestId', $testId);
$newsub = $db->update('teachertest', $sdata);
if ($newsub) {
echo "Subject was changed and";
}
$tdata = array(
'Question' => $question,
'Answer' => $answer,
);
$db->where('TestId', $testId);
$newdb = $db->update('testdetails', $tdata);
if ($newdb) {
echo "Test item details were updated!";
}
}
?>
I am create widget in magento 2.3 that extend funcitonality of vendor Catalog List Product. By default Catalog List Product (CLP) does not allow to create and handle several condition control on same page. My widget allow to create several condition control.
Technically each my conditions control open in new modal window.
When the user need to create condition then he must click on button named "Choose"
Modal window opens and user set the conditions. When the user configures and ready to save condition then he click to button named "Save" on modal window ajax request sending to server and server respond decoded value to parent form input. The user close modal window and click on Save button on parent form. Widget saved. All done. Everything is right until this step:
When user want to edit saved widget and opens modal window saved data converts to aplicable form by another ajax and jQuery Prepend newchild
< li >
to < ul >
But prepended data becomes not interactable- user cannot edit and delete loaded rule.
widget.xml
<parameter name="cond1" xsi:type="block" visible="true" required="false">
<label translate="true">First Conditions</label>
<block class="MonteShot\MegaWidget\Block\Adminhtml\Conditions\Conditions">
<data>
<item name="condition" xsi:type="array">
<item name="id1" xsi:type="string" translate="true">1</item>
</item>
</data>
</block>
</parameter>
MonteShot\MegaWidget\Block\Adminhtml\Conditions\Conditions
<?php
namespace MonteShot\MegaWidget\Block\Adminhtml\Conditions;
use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Backend\Block\Widget\Tab\TabInterface;
use Magento\Widget\Block\BlockInterface;
/**
* Class Conditions
*/
class Conditions extends Generic implements TabInterface, BlockInterface
{
/**
* Conditions constructor.
* #param \Magento\Backend\Block\Template\Context $context
* #param \Magento\Framework\Data\FormFactory $formFactory
* #param \Magento\Rule\Block\Conditions $conditions
* #param \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset
* #param \Magento\Framework\Registry $coreRegistry
* #param \MonteShot\MegaWidget\Model\RuleFactory $ruleModelFactory
* #param \Magento\CatalogWidget\Model\RuleFactory $ruleFactory
* #param \Magento\Widget\Helper\Conditions $conditionsHelper
* #param \Magento\Cms\Model\PageFactory $pageFactory
* #param \Magento\Framework\App\Response\Http $response
* #param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Data\FormFactory $formFactory,
\Magento\Rule\Block\Conditions $conditions,
\Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset,
\Magento\Framework\Registry $coreRegistry,
\MonteShot\MegaWidget\Model\RuleFactory $ruleModelFactory,
\Magento\CatalogWidget\Model\RuleFactory $ruleFactory,
\Magento\Widget\Helper\Conditions $conditionsHelper,
\Magento\Cms\Model\PageFactory $pageFactory,
\Magento\Framework\App\Response\Http $response,
array $data = []
)
{
$this->response = $response;
$this->conditionsHelper = $conditionsHelper;
$this->ruleFactory = $ruleFactory;
$this->ruleModelFactory = $ruleModelFactory;
$this->_pageFactory = $pageFactory;
$this->coreRegistry = $coreRegistry;
$this->rendererFieldset = $rendererFieldset;
$this->conditions = $conditions;
parent::__construct($context, $coreRegistry, $formFactory, $data);
}
/**
* {#inheritdoc}
*/
public function getTabLabel()
{
return __('Conditions');
}
/**
/**
* #param \Magento\Framework\Data\Form\Element\AbstractElement $element
* #return \Magento\Framework\Data\Form\Element\AbstractElement
* #throws \Magento\Framework\Exception\LocalizedException
*/
public function prepareElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$uniqId = $this->mathRandom->getUniqueHash($element->getId());
$sourceUrl = $this->getUrl(
'megawidget/conditions_rule_conditioncontent/conditionpagecontroller',
[
'name' => $element->getData('name'),
'uniq_id' => $uniqId,
'button_num' => $this->getData('condition')[key($this->getData('condition'))]
]);
$chooser = $this->getLayout()->createBlock(
\MonteShot\MegaWidget\Block\Adminhtml\Widget\Chooser::class
)->setElement(
$element
)->setConfig(
$this->getConfig()
)->setFieldsetId(
$this->getFieldsetId()
)->setSourceUrl(
$sourceUrl
)->setUniqId(
$uniqId
)->setValue($this->getData('condition')[key($this->getData('condition'))]);
if ($element->getValue()) {
$page = $this->_pageFactory->create()->load((int)$element->getValue());
if ($page->getId()) {
$chooser->setLabel($this->escapeHtml($page->getTitle()));
}
}
$element->setData('after_element_html', $chooser->toHtml());
return $element;
}
/**
* Prepare form before rendering HTML
*
* #return Generic
* #throws \Magento\Framework\Exception\LocalizedException
*/
protected function _prepareForm()
{
$model = $this->ruleFactory->create();
// $model = $this->ruleModelFactory->create();
$id = $this->_request->getParam('uniq_id');
$name = $this->_request->getParam('name');
$cuttedName = trim(str_replace('parameters', '', $name), '[]');
/** #var \Magento\Framework\Data\Form $form */
$form = $this->_formFactory->create(
[
'data' => [
'id' => 'edit_form_modal',
'action' => $this->getUrl('megawidget/conditions_rule/savewidget',
[
'uniq_id' => $this->_request->getParam('uniq_id'),
'button_num' => $this->_request->getParam('button_num'),
'name' => $this->_request->getParam('name'),
]),
'method' => 'post',
],
]
);
$form->setUseContainer(true);
$form->setHtmlIdPrefix('rule_');
$this->getLayout()->createBlock("Magento\Widget\Block\Adminhtml\Widget\Options");
$renderer = $this->rendererFieldset->setTemplate(
'Magento_CatalogRule::promo/fieldset.phtml'
)->setNewChildUrl(
$this->getUrl('megawidget/conditions_rule/newConditionHtmlCatalog/form/rule_conditions_fieldset')
);
$fieldset = $form->addFieldset(
'conditions_fieldset',
[
'legend' => __(
'Apply the rule only if the following conditions are met (leave blank for all products).'
)
]
)->setRenderer(
$renderer
);
// $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
// $model->setData('element_value', substr_replace($_POST['element_value'], '', 0, 26));
$model->getConditions()->setJsFormObject('rule_conditions_fieldset');
$fieldset->addField(
'conditions',
'text',
['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions')]
)->setRule(
$model
)->setRenderer(
$this->conditions
);
$label = $id . 'label';
$valueId = $id . 'value';
$fieldset->addField(
'button-save',
'hidden',
['name' => 'select',
'label' => __('Save condition'),
'title' => __('Save condition'),
'class' => 'action-close',
'data-role' => 'closeBtn',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'saveandcontinue', 'target' => '#edit_form']],
],
'after_element_html' => '
<button data-role="closeBtn" id="rule_button-save-submit-' . $cuttedName . '" type="button">Save</button>
<script>
require([\'jquery\',\'jqueryForm\',\'Magento_Ui/js/modal/modal\'], function (jQuery,jqueryForm,modal){
jQuery(document).on(\'click\', "#rule_button-save-submit-' . $cuttedName . '", function () {
var serArr=JSON.stringify(jQuery("#edit_form_modal").serializeArray());
jQuery.ajax({
url: "' . $this->getUrl("megawidget/conditions_rule/preparedata") . '",
data: { form_key: window.FORM_KEY,serializedArray:serArr},
type: \'post\',
success: function (response) {
console.log(response.data);
jQuery("input[name=\'' . $name . '\']")[0].value=response.data;
},
error: function (response) {
alert(response.message);
console.log(response.message);
}
});
});
});
</script>
']);
$fieldset->addField(
'script-area',
'hidden',
['name' => 'select',
'class' => 'script-area-hidden',
'data_attribute' => [
'mage-init' => ['hidden' => ['event' => 'saveandcontinue', 'target' => '#edit_form_modal']],
],
'after_element_html' => '
<script>
require([\'jquery\',\'jqueryForm\'],
function ($,jqueryForm){
jQuery(document).ready(function (jQuery) {
jQuery.ajax({
url: "' . $this->getUrl("megawidget/conditions_rule/newConditionHtmlCatalog/form/rule_conditions_fieldset") . '",
data: {JsonToHtml:jQuery("input[name=\'' . $name . '\']")[0].value, form: window.FORM_KEY},
type: \'post\',
success: function (response) {
console.log(response.data);
jQuery(document.querySelector("#conditions__1__children")).prepend(response.data);
},
error: function (response) {
alert(response.message);
console.log(response.message);
}
});
});
});
</script>
']);
// $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
$form->setValues($model->getData());
$this->setForm($form);
return parent::_prepareForm();
}
}
//Magento\Widget\Helper\Conditions encode when save button has been pressed
And code in modal window
$model = $this->ruleFactory->create();
// $model = $this->ruleModelFactory->create();
$id = $this->_request->getParam('uniq_id');
$name = $this->_request->getParam('name');
$cuttedName = trim(str_replace('parameters', '', $name), '[]');
/** #var \Magento\Framework\Data\Form $form */
$form = $this->_formFactory->create(
[
'data' => [
'id' => 'edit_form_modal',
'action' => $this->getUrl('megawidget/conditions_rule/savewidget',
[
'uniq_id' => $this->_request->getParam('uniq_id'),
'button_num' => $this->_request->getParam('button_num'),
'name' => $this->_request->getParam('name'),
]),
'method' => 'post',
],
]
);
$form->setUseContainer(true);
$form->setHtmlIdPrefix('rule_');
$this->getLayout()->createBlock("Magento\Widget\Block\Adminhtml\Widget\Options");
$renderer = $this->rendererFieldset->setTemplate(
'Magento_CatalogRule::promo/fieldset.phtml'
)->setNewChildUrl(
$this->getUrl('megawidget/conditions_rule/newConditionHtmlCatalog/form/rule_conditions_fieldset')
);
$fieldset = $form->addFieldset(
'conditions_fieldset',
[
'legend' => __(
'Apply the rule only if the following conditions are met (leave blank for all products).'
)
]
)->setRenderer(
$renderer
);
// $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
// $model->setData('element_value', substr_replace($_POST['element_value'], '', 0, 26));
$model->getConditions()->setJsFormObject('rule_conditions_fieldset');
$fieldset->addField(
'conditions',
'text',
['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions')]
)->setRule(
$model
)->setRenderer(
$this->conditions
);
// $fieldset->addElement($this->getLayout()->createBlock(\MonteShot\MegaWidget\Renderer\Conditions::class));
$label = $id . 'label';
$valueId = $id . 'value';
$fieldset->addField(
'button-save',
'hidden',
['name' => 'select',
'label' => __('Save condition'),
'title' => __('Save condition'),
'class' => 'action-close',
'data-role' => 'closeBtn',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'saveandcontinue', 'target' => '#edit_form']],
],
'after_element_html' => '
<button data-role="closeBtn" id="rule_button-save-submit-' . $cuttedName . '" type="button">Save</button>
<script>
require([\'jquery\',\'jqueryForm\',\'Magento_Ui/js/modal/modal\'], function (jQuery,jqueryForm,modal){
jQuery(document).on(\'click\', "#rule_button-save-submit-' . $cuttedName . '", function () {
var serArr=JSON.stringify(jQuery("#edit_form_modal").serializeArray());
jQuery.ajax({
url: "' . $this->getUrl("megawidget/conditions_rule/preparedata") . '",
data: { form_key: window.FORM_KEY,serializedArray:serArr},
type: \'post\',
success: function (response) {
console.log(response.data);
jQuery("input[name=\'' . $name . '\']")[0].value=response.data;
},
error: function (response) {
alert(response.message);
console.log(response.message);
}
});
});
});
</script>
']);
$fieldset->addField(
'script-area',
'hidden',
['name' => 'select',
'class' => 'script-area-hidden',
'data_attribute' => [
'mage-init' => ['hidden' => ['event' => 'saveandcontinue', 'target' => '#edit_form_modal']],
],
'after_element_html' => '
<script>
require([\'jquery\',\'jqueryForm\'],
function ($,jqueryForm){
jQuery(document).ready(function (jQuery) {
jQuery.ajax({
url: "' . $this->getUrl("megawidget/conditions_rule/newConditionHtmlCatalog/form/rule_conditions_fieldset") . '",
data: {JsonToHtml:jQuery("input[name=\'' . $name . '\']")[0].value, form: window.FORM_KEY},
type: \'post\',
success: function (response) {
console.log(response.data);
jQuery(document.querySelector("#conditions__1__children")).prepend(response.data);
},
error: function (response) {
alert(response.message);
console.log(response.message);
}
});
});
});
</script>
']);
$form->setValues($model->getData());
$this->setForm($form);
return parent::_prepareForm();
}
PrepareData Controller
<?php
/**
* Copyright (c) 2019. MonteShot
*/
namespace MonteShot\MegaWidget\Controller\Adminhtml\Conditions\Rule;
use Magento\Framework\Json\Helper\Data as JsonHelper;
/**
* Class PrepareData
*/
class PrepareData extends \MonteShot\MegaWidget\Controller\Adminhtml\Conditions\Rule
{
/**
* #param \Magento\Backend\App\Action\Context $context
* #param \Magento\Framework\Registry $coreRegistry
* #param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
* #param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
* #param \MonteShot\MegaWidget\Model\RuleFactory $ruleFactory
* #param \Magento\Widget\Helper\Conditions $conditionsHelper
* #param \Psr\Log\LoggerInterface $logger
* #param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
* #param JsonHelper $jsonHelper
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\Registry $coreRegistry,
\Magento\Framework\App\Response\Http\FileFactory $fileFactory,
\Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
\MonteShot\MegaWidget\Model\RuleFactory $ruleFactory,
\Magento\Widget\Helper\Conditions $conditionsHelper,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
JsonHelper $jsonHelper
)
{
$this->jsonHelper = $jsonHelper;
$this->resultJsonFactory = $resultJsonFactory;
$this->conditionsHelper = $conditionsHelper;
parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter, $ruleFactory, $logger);
}
/**
* #return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface|void
*/
public function execute()
{
if (!$this->getRequest()->getPostValue()) {
$this->_redirect('megawidget/*/');
}
try {
$serializedConditionArray =
$this->conditionsHelper->decode($this->getRequest()->getParam('serializedArray'));
$templateArray = [];
foreach ($serializedConditionArray as $index => $singleArrItem) {
if ($singleArrItem['name'] == 'form_key') {
unset($serializedConditionArray[$index]);
continue;
}
if ($singleArrItem['name'] == 'select') {
unset($serializedConditionArray[$index]);
continue;
}
if (!empty($templateArray[str_replace('rule', '', $singleArrItem['name'])])) {
$templateArray[str_replace('rule', '', $singleArrItem['name'])] .= ',' . $singleArrItem['value'];
} else {
$templateArray[str_replace('rule', '', $singleArrItem['name'])] = $singleArrItem['value'];
}
//$templateArray[str_replace('rule', '', $singleArrItem['name'])] = $singleArrItem['value'];
}
$finalArr = [];
foreach ($templateArray as $index => $data) {
$indexName = $this->get_string_between(str_replace('[conditions]', '', $index), '[', ']');
$paramName = $this->get_string_between(str_replace('[conditions][' . $indexName . ']', '', $index), '[', ']');
$multiValue = str_replace('parameters[conditions][' . $indexName . ']' . '[' . $paramName . ']', '', $index);
if ($paramName == 'value' && strpos($data, ',')) {
$finalArr[$indexName][$paramName] = [$data];
} else {
$finalArr[$indexName][$paramName] = $data;
}
if ($paramName == 'value' && $multiValue == '[]') {
if ($finalArr[$indexName][$paramName]) {
if ($finalArr[$indexName][$paramName]) {
$temp = $finalArr[$indexName][$paramName];
unset($finalArr[$indexName][$paramName]);
$finalArr[$indexName][$paramName][0] = $data;
} else {
$finalArr[$indexName][$paramName][0] .= ',' . $data;
}
} else {
$finalArr[$indexName][$paramName][0] = [$data];
}
}
}
$this->data = $this->conditionsHelper->encode($finalArr);
$this->message = 'success';
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
$id = (int)$this->getRequest()->getParam('rule_id');
if (!empty($id)) {
$this->_redirect('megawidget/*/edit', ['id' => $id]);
} else {
$this->_redirect('megawidget/*/new');
}
return;
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(
__('Something went wrong while saving the rule data. Please review the error log.')
);
$this->error = $e->getMessage();
$this->message = 'success';
$this->logger->critical($e);
$data = !empty($data) ? $data : [];
$this->_session->setPageData($data);
$this->_redirect('megawidget/*/edit', ['id' => $this->getRequest()->getParam('rule_id')]);
return;
}
$resultJson = $this->resultJsonFactory->create();
$resultData = substr(substr($this->jsonHelper->jsonEncode($this->data), 1), 0, -1);
return $resultJson->setData([
'message' => $this->message,
'data' => $resultData,
'error' => $this->error
]);
}
protected function get_string_between($string, $start, $end)
{
$string = ' ' . $string;
$ini = strpos($string, $start);
if ($ini == 0) return '';
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}
}
Controller that return data that ready to prepend in jQuery
<?php
/**
* Copyright (c) 2019. MonteShot
*/
namespace MonteShot\MegaWidget\Controller\Adminhtml\Conditions\Rule;
use Magento\Framework\Json\Helper\Data as JsonHelper;
class NewConditionHtmlCatalog extends \MonteShot\MegaWidget\Controller\Adminhtml\Conditions\Rule
{
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\Registry $coreRegistry,
\Magento\Framework\App\Response\Http\FileFactory $fileFactory,
\Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
\MonteShot\MegaWidget\Model\RuleFactory $ruleFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Widget\Helper\Conditions $conditions,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
JsonHelper $jsonHelper,
\Magento\CatalogWidget\Model\RuleFactory $ruleCatalogFactory,
\Magento\Rule\Model\Condition\CombineFactory $combineModelFactory
)
{
$this->combineModelFactory = $combineModelFactory;
$this->ruleCatalogFactory = $ruleCatalogFactory;
$this->jsonHelper = $jsonHelper;
$this->resultJsonFactory = $resultJsonFactory;
$this->conditions = $conditions;
parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter, $ruleFactory, $logger);
}
public function execute()
{
if (!empty($this->getRequest()->getParam('id'))) {
$id = $this->getRequest()->getParam('id');
$typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
$type = $typeArr[0];
$model = $this->_objectManager->create(
$type
)->setId(
$id
)->setType(
$type
)->setRule(
$this->ruleFactory->create()
)->setPrefix(
'conditions'
);
if (!empty($typeArr[1])) {
$model->setAttribute($typeArr[1]);
}
if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
$model->setJsFormObject($this->getRequest()->getParam('form'));
$html = $model->asHtmlRecursive();
} else {
$html = '';
}
return $this->getResponse()->setBody($html);
} elseif (!empty($this->getRequest()->getParam('JsonToHtml'))) {
$conditionDecoded = $this->conditions->decode($this->getRequest()->getParam('JsonToHtml'));
foreach ($conditionDecoded as $idx => $condition) {
if ($idx == '1') {
continue;
} else {
$id = $idx;
$type = $conditionDecoded[$idx]['type'];
$rule = $this->ruleCatalogFactory->create();
// $rule->setConditions($conditionDecoded);
$combineModel = $this->combineModelFactory->create();
$combineModel->loadArray($conditionDecoded);
$validateResult = $rule->validateData(new \Magento\Framework\DataObject($rule->getData()));
if ($validateResult !== true) {
foreach ($validateResult as $errorMessage) {
$this->message = $errorMessage;
}
return;
}
$rule->loadPost($rule->getData());
$model = $this->_objectManager->create(
$type
)->setId(
$id
)->setType(
$type
)->setPrefix(
'conditions'
)->setData(
'conditions', $rule
)->setRule(
$rule
);
if (!empty($conditionDecoded[$idx]['attribute'])) {
$model->setAttribute($conditionDecoded[$idx]['attribute']);
}
if (!empty($conditionDecoded[$idx]['value'])) {
$model->setValue($conditionDecoded[$idx]['value']);
}
}
if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
// if (empty($this->data)) {
// $model->setJsFormObject($this->getRequest()->getParam('form'));
// $this->data = '<li class>' . $model->asHtmlRecursive() . '</li>';
// $this->data = $model->asHtmlRecursive();
// } else {
$model->setJsFormObject($this->getRequest()->getParam('form'));
$this->data = '<li class>' . $model->asHtmlRecursive() . '</li>';
//$this->data = $this->data . "\n" . '<li class>' . $model->asHtmlRecursive() . '</li>';
// }
} else {
$this->data = '';
}
$this->getResponse()->setBody($this->data);
}
}
}
// return $this->getResponse()->setBody($this->data);
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData([
'message' => $this->message,
'data' => $this->data,
'error' => $this->error
]);
}
}
How i can return interactivity to loaded data
protected function _prepareForm()
{
$model = $this->ruleFactory->create();
// $model = $this->ruleModelFactory->create();
$id = $this->_request->getParam('uniq_id');
$name = $this->_request->getParam('name');
$cuttedName = trim(str_replace('parameters', '', $name), '[]');
// if ($this->ruleResourceCollection->getSize() == 0) {
//
// } else {
// if (!$id) {
// $model = $this->ruleResourceCollection
// ->addFieldToFilter(\MonteShot\MegaWidget\Model\Rule::UNIQ_BUTTON_ID,
// $id
// )->load();
// }
// }
/** #var \Magento\Framework\Data\Form $form */
$form = $this->_formFactory->create(
[
'data' => [
'id' => 'edit_form_modal',
'action' => $this->getUrl('megawidget/conditions_rule/savewidget',
[
'uniq_id' => $this->_request->getParam('uniq_id'),
'button_num' => $this->_request->getParam('button_num'),
'name' => $this->_request->getParam('name'),
]),
'method' => 'post',
],
]
);
$form->setUseContainer(true);
$form->setHtmlIdPrefix('rule_');
$this->getLayout()->createBlock("Magento\Widget\Block\Adminhtml\Widget\Options");
$renderer = $this->rendererFieldset->setTemplate(
'Magento_CatalogRule::promo/fieldset.phtml'
)->setNewChildUrl(
$this->getUrl('megawidget/conditions_rule/newConditionHtmlCatalog/form/rule_conditions_fieldset')
);
$fieldset = $form->addFieldset(
'conditions_fieldset',
[
'legend' => __(
'Apply the rule only if the following conditions are met (leave blank for all products).'
)
]
)->setRenderer(
$renderer
);
$model->getConditions()->setJsFormObject('rule_conditions_fieldset');
try {
$conditions = $this->conditionsHelper->decode($this->getRequest()->getParam('element_value'));
$model->loadPost(['conditions' => $conditions]);
} catch (\InvalidArgumentException $invalidArgumentException) {
//do nothing
}
$element = $fieldset->addField(
'condition',
'text',
['name' => 'conditions',
'label' => __('Condition'),
'title' => __('Condition'),
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'saveandcontinue', 'target' => '#edit_form_modal']],
]
])
->setRule(
$model
)->setRenderer(
$this->conditions
);
$sourceUrl = $this->getUrl(
'megawidget/conditions_rule_conditioncontent/conditionmodalpagecontroller');
$condition = $this->getLayout()->createBlock(
\MonteShot\MegaWidget\Block\Adminhtml\Widget\Options::class
)->setElement(
$element
)->setConfig(
$this->getConfig()
)->setFieldsetId(
$this->getFieldsetId()
)->setSourceUrl(
$sourceUrl
)->setConfig(
$this->getConfig()
)->setFieldsetId(
$this->getFieldsetId()
)->setUniqId(
$id
);
// $fieldset->addElement($this->getLayout()->createBlock(\MonteShot\MegaWidget\Renderer\Conditions::class));
$label = $id . 'label';
$valueId = $id . 'value';
$fieldset->addField(
'button-save',
'hidden',
['name' => 'select',
'label' => __('Save condition'),
'title' => __('Save condition'),
'class' => 'action-close',
'data-role' => 'closeBtn',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'saveandcontinue', 'target' => '#edit_form']],
],
'after_element_html' => '
<button data-role="closeBtn" id="rule_button-save-submit-' . $cuttedName . '" type="button">Save</button>
<script>
require([\'jquery\',\'jqueryForm\',\'Magento_Ui/js/modal/modal\'], function (jQuery,jqueryForm,modal){
jQuery(document).on(\'click\', "#rule_button-save-submit-' . $cuttedName . '", function () {
var serArr=JSON.stringify(jQuery("#edit_form_modal").serializeArray());
jQuery.ajax({
url: "' . $this->getUrl("megawidget/conditions_rule/preparedata") . '",
data: { form_key: window.FORM_KEY,serializedArray:serArr},
type: \'post\',
success: function (response) {
console.log(response.data);
jQuery("input[name=\'' . $name . '\']")[0].value=response.data;
},
error: function (response) {
alert(response.message);
console.log(response.message);
}
});
});
});
</script>
']);
$form->setValues($model->getData());
$this->setForm($form);
return parent::_prepareForm();
}