Yii 2.0 hidden field value not modifiable using javascript - yii

In my model I have a hidden field.I am modifying its value using javascript (jQuery).But when I submit the form to model, it still contains its initial value instead of values modified via javascript.I have checked whether javascript is modifying the values, and is confirmed that values are being modified.But when form is submitted it is sending initial values.
Code is given below
<?php
/*Model -- wrong_answers is my hidden field*/
namespace app\models;
use yii;
use yii\db;
use yii\base\Model;
use yii\web\UploadedFile;
class QuestionModel extends Model
{
public $quiz_id = null;
public $question = '';
public $choices = '';
public $explanation ="";
public $hints = array();
public $correct_answer = "";
public $wrong_answers = '{}';//when populating from already entered data use {"a":"as"} format instead of {'a':'as'}
public $wrong_answer = "";
public function rules()
{
return [
[['quiz_id'], 'safe'] ,
[['question'], 'required'] ,
[['correct_answer'], 'required'] ,
[['wrong_answers'], 'safe'] ,
[['wrong_answer'], 'safe'] ,
[['explanation'],'required']
];
}
public function get_quiz($quiz_id) {
$ret = array();
$command = Yii::$app->db->createCommand("CALL get_quiz(:qz_id)");
$command->bindParam(":qz_id", $this->quiz_id);
$result = $command->queryAll();
if(sizeof($result) > 0) {
$ret = $result[0] ;
}
return $ret;
}
public function save_question() {
$ret = false;
//echo "quiz- id is ".$this->quiz_id;
$quiz_details = $this->get_quiz($this->quiz_id);
if(sizeof($quiz_details)) {
$quiz_data = $quiz_details['quiz_data'];
$quiz_data = json_decode($quiz_data);
$choices = [];
echo $this->wrong_answers;
exit;
$wrong_answers_array = json_decode($this->wrong_answers);
if($this->wrong_answer)
array_push($wrong_answers_array, $this->wrong_answer);
print_r($wrong_answers_array);
exit;
foreach($wrong_answers_array as $wr_ans) {
array_push($choices,array('choice'=>$wr_ans));
}
$question_data = array('question'=>$this->question,'explanation'=>$this->explanation,'choices'=>$choices);
$ret = false;
}
return $ret;
}
public function getHint($key) {
return $this->hints[$key];
}
}
Controller - actionAdd_question is the action
<?php
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\QuizModel;
use app\models\QuestionModel;
use yii\web\UploadedFile;
global $username;
class QuizController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
public function actionEntry()
{
}
public function actionView_all() {
$request = Yii::$app->request;
$layout_params=array(
'username'=>'admin',
'sidebar_menu1_class' =>'active',
'sidebar_menu12_class' =>'active',
'dash_title' => 'Courses',
'dash_sub_title'=>'View all'
);
$message = '';
$data = array();
$layout_params['scripts'] = array("view-all-modules.js");
/*$model = new ViewAllCompaniesModel();
$pagination_data = $model->getTotalCompanies();
$layout_params['js_variables'] = array(
'totalCompanyPages'=>$pagination_data['total_page_count'],
'csrfToken' => "'".$request->csrfToken."'" ,
'csrfTokenName' => "'".$request->csrfParam."'"
);
*/
return $this->render('view-all-modules', [
'layout_params'=>$layout_params,
'message' =>$message,
'data' =>$data
]);
}
public function actionAdd() {
$layout_params=array(
'username'=>'admin',
'sidebar_menu1_class' =>'active',
'sidebar_menu12_class' =>'active',
'dash_title' => 'Quiz',
'dash_sub_title'=>'Add new quiz'
);
$message = array();
$request = Yii::$app->request;
$proceed = true;
$parent_course_id = null;
$req_params = $_POST;
$layout_params['scripts'] = array("add-quiz.js");
$model = new QuizModel();
if(!$model->quiz_id) {
if ($model->load($request->post()) && $model->validate()) {
$params = $request->post();
$model->save_quiz();
$message['title'] = 'Wow !';
$message['body'] = 'Successfully added quiz '.$model->quiz_title;
} else {
}
} else {
}
return $this->render('add-quiz', ['model' => $model,
'layout_params'=>$layout_params,
'message' =>$message
]);
//return $this->render('add-company',$data);
}
public function actionSave() {
//print_r($_POST);
}
public function actionAdd_question() {
print_r($_POST);
$layout_params=array(
'username'=>'admin',
'sidebar_menu1_class' =>'active',
'sidebar_menu12_class' =>'active',
'dash_title' => 'Quiz',
'dash_sub_title'=>'Add question'
);
$request = Yii::$app->request;
$message = array();
$layout_params['scripts'] = array("add-question.js");
$model = new QuestionModel();
if($request->get('q_id')) {
$model->quiz_id = $request->get('q_id');
if ($model->load($request->post()) && $model->validate()) {
$model->save_question();
} else {
echo "yo yo";
}
return $this->render('add-question', ['model' => $model,
'layout_params'=>$layout_params,
'message' =>$message
]);
} else {
}
}
public function actionIndex()
{
$data = array(
'layout_params'=>array(
'username'=>'admin',
'sidebar_menu11_class' =>'active'
)
);//
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
}
View
/*Assigning the parameters to be accessible by layouts*/
foreach($layout_params as $layout_param => $value) {
$this->params[$layout_param] = $value;
}
?>
<div class="form-group">
</div>
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Add Question</h3>
</div><!-- /.box-header -->
<!-- form start -->
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<input type = 'hidden' id = 'test' name = 'test' />
<div class="box-body">
<?php if(isset($message)&&sizeof($message)): ?>
<div class="form-group">
<div class="callout callout-info alert-dismissible">
<h4><?php if(isset($message['title']))echo $message['title'];?></h4>
<p>
<?php if(isset($message['body']))echo $message['body'];?>
</p>
</div>
</div>
<?php endif;?>
<div class="form-group">
<?= $form->field($model, 'question')->textInput(array('class'=>'form-control')); ?>
</div>
<div class="form-group">
<?= $form->field($model, 'correct_answer')->textInput(array("class"=>"form-control",'id'=>'correct_answer')); ?>
<?= Html::activeHiddenInput($model, 'wrong_answers',array('id'=>'wrong_answers')) ;?>
<?= Html::activeHiddenInput($model, 'quiz_id',array('id'=>'quiz_id')) ;?>
</div>
<div class="form-group">
<?= $form->field($model, 'wrong_answer')->textInput(array("class"=>"form-control ",'id'=>'wrong_answer')); ?>
<button id = 'add-answer' type = "button">Add Another</button>
<?= Html::activeHiddenInput($model, 'wrong_answers',array('id'=>'wrong_answers')) ;?>
<?= Html::activeHiddenInput($model, 'quiz_id',array('id'=>'quiz_id')) ;?>
</div>
<div class="form-group" id ='wrong-group'>
<h3>Wrong Answers</h3>
<!-- The following dummy html is used for generating html inside javascript -->
<ul class="edit-list-dummy" id ="edit-list-dummy">
<li> <button class="btn btn-danger" id = 'dummy-wrong-ans-delete' onClick = "deleteWrongAnswer(this.name)" type ="button">Delete</button> <span id ='dummy-wrong-answer'>Hello I am a wrong answer here</span>
</ul>
<ul class="edit-list" id = 'wrong-answers'>
</ul>
</div>
<div class="form-group">
<?= $form->field($model, 'explanation')->textArea(array("class"=>"form-control",'id'=>'explanation')); ?>
</div>
</div><!-- /.box-body --> <div class="box-footer">
<?= Html::submitButton('Save Question', ['class' => 'btn btn-primary','onclick'=>'this.preventDefault']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
Javascript -#wrong_answers is my hidden input id
var wrongAnswers = {};//{1:answer1,2:answer2...};
var randCount = 0;//radom count for setting as wrongAnswers attribute
//initialise wrong answers json from database
$(document).ready(function() {
console.log($('#wrong_answers').val());
wrongAnswers = jQuery.parseJSON($('#wrong_answers').val());
console.log(wrongAnswers);
$('#add-answer').click(function() {
var wrongAns = $('#wrong_answer').val().trim();
if(wrongAns) {
wrongAnswers[randCount] = wrongAns;
randCount++;
generateWrongAnswers();
$('#wrong_answer').val("");
// alert($('#wrong_answers').val());
}
});
generateWrongAnswers();
});
function generateWrongAnswers() {
$('#wrong-group').hide();
var html = '';
for(var wrongIdx in wrongAnswers) {
//console.log("w is ".wrongAnsIdx);
$('#dummy-wrong-answer').html(wrongAnswers[wrongIdx]);
$('#dummy-wrong-ans-delete').attr('name',wrongIdx);
html += $('#edit-list-dummy').html();
}
if(html) {
$('#wrong-group').show();
$('#wrong-answers').html(html);
}
var jsonData = JSON.stringify(wrongAnswers);
$('#wrong_answers').val(jsonData);
// $('#test').val(jsonData);
//$('#correct_answer').val("Mallu");
// alert($('#wrong_answers').val());
}
function deleteWrongAnswer(idx) {
delete wrongAnswers[idx];
generateWrongAnswers() ;
}

Finall solved it. The issue is that, I accidentally included two hidden input fields with same id.Removed one and solved

Related

Prestashop after submit return page html

Hello I develop a module under Prestashop 1.6 and I am blocked on the submission of a form.
I add in my module a form with the hook "DisplayAdminOrderContentShip" which retrieves a tpl hook_button.tpl which displays my form (button)
relance
here is my tpl:
<div class="panel panel-default">
<div class="panel-heading">
<p>Export commande mecalux</p>
</div>
<div class="panel-body">
<p>Permet de relancer l'export vers Mecalux de la commande</p>
<form method="POST" action="#">
<button type="submit" value="1" id="exportordersubmit" name="exportordersubmit" class="btn btn-default pull-right">
<i class="process-icon-refresh"></i> {l s='Relancer l\'export' mod='exportorders'}
</button>
</form>
</div>
Here is my function:
public function hookDisplayAdminOrderContentShip($params)
{
$order = new Order(Tools::getValue('id_order'));
$status = (int)Configuration::get('EXPORTORDERS_STATUS_TRANSFERED_TO_WMS');
$statusError = (int)Configuration::get('EXPORTORDERS_STATUS_CMD_ERROR');
if (Tools::isSubmit('exportordersubmit')) {
if (isset($order) && (int)$order->valid == 1) {
if ($order->current_state != $status && $order->current_state != $statusError) {
return;
}
if (!$order->valid) {
return;
}
$customer = $order->getCustomer();
$deliveryAddress = new Address($order->id_address_delivery);
$id_country_delivery = $deliveryAddress->getCountryAndState($order->id_address_delivery);
$iso = new Country();
$userXml = [
'id_client' => $customer->id,
'email' => $customer->email,
'livraison' => $deliveryAddress,
'country_code_delivery' => $iso->getIsoById($id_country_delivery['id_country'])
];
$dateOrder = new DateTime($order->date_add);
$orderXml = [
'id' => $order->id,
'sorCode' => $order->reference,
'payment' => $order->payment,
'date' => $dateOrder->format('Y-m-d\TH:i:s') . 'Z',
];
$result = $this->fileXml($userXml, $orderXml, $order->getProducts());
if ((int)$result === 1) {
$order->setCurrentState($statusError, (int)$this->context->employee->id ? (int)$this->context->employee->id : 0);
$html = [
'message' => $this->displayError('Erreur de transmission au WMS'),
];
} else {
if ((int)$order->current_state !== (int)$status) {
$order->setCurrentState($status, (int)$this->context->employee->id ? (int)$this->context->employee->id : 0);
$order->wms_transfered = 1;
$order->save();
$html = [
'message' => $this->displayConfirmation('Transmise au WMS'),
];
}
}
}
}
$this->context->smarty->assign(
array(
'alert' => $html
)
);
return ($this->display(__FILE__, 'views/templates/hook/hook_button.tpl'));
}
and when I click here is the result of my page:
html
normally it should return an alert in the order detail page (admin) I do not see where my problem comes from have any idea?
Thank you for your help.
fetch

Yii2 Dynamic Form

I'm using wbraganca's dynamicform samples codes for mine own project. My code with its corresponding errors are as follows.
Under the view folder
_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use frontend\models\Items;
use frontend\models\Employees;
use frontend\models\Departments;
use dosamigos\datepicker\DatePicker;
use wbraganca\dynamicform\DynamicFormWidget;
/* #var $this yii\web\View */
/* #var $model backend\models\Borrow */
/* #var $form yii\widgets\ActiveForm */
$js = '
jQuery(".dynamicform_wrapper").on("afterInsert", function(e, item) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Items: " + (index + 1))
});
});
jQuery(".dynamicform_wrapper").on("afterDelete", function(e) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Items: " + (index + 1))
});
});
';
$this->registerJs($js);?>
<div class="borrow-form">
<?php $form = ActiveForm::begin(['id'=>'dynamic-form']); ?>
<div class="row">
<div class="col-xs-4">
<?= $form->field($model,'dept_id')->dropDownList(
ArrayHelper::map(Departments::find()->all(),'id','dept_name'),
['prompt'=>'select departments'])
?>
</div>
<div class="col-xs-4">
<?=$form->field($model, 'return_date')->widget(
DatePicker::className(), [
'inline' => false,
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
</div>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<!-- beginning of dynamic form -->
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 10, // the maximum times, an element can be added (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $modelsAddress[0],
'formId' => 'dynamic-form',
'formFields' => [
'items_id',
'unit',
'request',
'allowed',
],
]); ?>
<div class="panel panel-default">
<div class="panel-heading">
<h4><i class="glyphicon glyphicon-envelope"></i> Items
</h4>
</div>
<div class="panel-body">
<div class="container-items"><!-- widgetBody -->
<?php foreach ($modelsAddress as $i => $modelAddress): ?>
<div class="item panel panel-default"><!-- widgetItem -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Items</h3>
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelAddress->isNewRecord) {
echo Html::activeHiddenInput($modelAddress, "[{$i}]id");
}
?>
<div class="row">
<div class="col-xs-4">
<?= $form->field($modelAddress, "[{$i}]items_id")->dropDownList(
ArrayHelper::map(Items::find()->all(),'id','item_name'),
['prompt'=>'select items']) ?>
</div>
<div class="col-xs-2">
<?= $form->field($modelAddress, "[{$i}]unit")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-xs-2">
<?= $form->field($modelAddress, "[{$i}]request")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-xs-2">
<?= $form->field($modelAddress, "[{$i}]allowed")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-xs-2">
<?= $form->field($modelAddress, "[{$i}]unit_price")->textInput(['maxlength' => true]) ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div><!-- .panel -->
<?php DynamicFormWidget::end(); ?>
<!-- end dynamic form-->
<div class="row">
<div class="col-xs-5">
<?= $form->field($model,'emp_id')->dropDownList(
ArrayHelper::map(Employees::find()->all(),'id','emp_name'),
['prompt'=>'select employees'])
?>
<?= $form->field($model,'head_id')->dropDownList(
ArrayHelper::map(Employees::find()->all(),'id','emp_name'),
['prompt'=>'select dept heads'])
?>
<?= $form->field($model,'man_id')->dropDownList(
ArrayHelper::map(Employees::find()->all(),'id','emp_name'),
['prompt'=>'select stoke managers'])
?>
<?= $form->field($model,'keeper_id')->dropDownList(
ArrayHelper::map(Employees::find()->all(),'id','emp_name'),
['prompt'=>'select stoke keepers'])
?>
</div>
<div class="col-xs-5">
<?=$form->field($model, 'emp_date')->widget(
DatePicker::className(), [
'inline' => false,
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
<?=$form->field($model, 'head_date')->widget(
DatePicker::className(), [
'inline' => false,
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
<?=$form->field($model, 'man_date')->widget(
DatePicker::className(), [
'inline' => false,
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
<?=$form->field($model, 'keeper_date')->widget(
DatePicker::className(), [
'inline' => false,
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
The create action under the controller
public function actionCreate()
{
$model = new Borrow();
$modelsAddress = [new Borrow];
if ($model->load(Yii::$app->request->post())) {
$modelsAddress = Model::createMultiple(Borrow::classname());
Model::loadMultiple($modelsAddress, Yii::$app->request->post());
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsAddress) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsAddress as $modelAddress) {
$modelAddress->id = $model->id;
if (! ($flag = $modelAddress->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('create', [
'model' => $model,
'modelsAddress' => (empty($modelsAddress)) ? [new Address] : $modelsAddress
]);
}
The Model Class under the Model Folder
<?php
namespace frontend\models;
use Yii;
use yii\helpers\ArrayHelper;
class Model extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $i => $borrow) {
if (isset($borrow['id']) && !empty($borrow['id']) && isset($multipleModels[$borrow['id']])) {
$models[] = $multipleModels[$borrow['id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
}
}
It gives the following error when I run my code:
PHP Fatal Error – yii\base\ErrorException Class 'frontend\controllers\Model' not found as shown below.
It looks like you have not namespaced frontend\models\Model in the controller.
Add there at the beginning:
use frontend\models\Model;

Symfony 3 form + Aurelia

So i've playing around with building a web app in Symfony 3, using a form type and rendering the form on the page. I am starting to Aurelia, and am trying to render a Symfony form on the page via an Aurelia custom element, and then post the form back to symfony. I've gotten to the point of validating the form upon submit, but it never validates. Can someone please look over the below code and see if i'm missing something somewhere?
Form type:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Service\PayeeService;
class PayeeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class)
->add('category', ChoiceType::class, [
'choices' => [
'Uncategorized' => PayeeService::CATEGORY_UNCATEGORIZED,
'Installment Loan' => PayeeService::CATEGORY_INSTALLMENT_LOAN,
'Credit Card' => PayeeService::CATEGORY_CREDIT_CARD,
'Utility' => PayeeService::CATEGORY_UTILITY,
'Mortgage' => PayeeService::CATEGORY_MORTGAGE,
'Entertainment' => PayeeService::CATEGORY_ENTERTAINMENT
],
'choices_as_values' => true
])
->add('amount', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
->add('frequency', ChoiceType::class, [
'choices' => [
'Recurring' => PayeeService::FREQUENCY_RECURRING,
'One-time' => PayeeService::FREQUENCY_ONETIME
],
'choices_as_values' => true
])
->add('method', ChoiceType::class, [
'choices' => [
'ACH' => PayeeService::PAY_METHOD_ACH,
'Check' => PayeeService::PAY_METHOD_CHECK
],
'choices_as_values' => true
])
->add('dateLastPaid', DateType::class)
->add('dueDate', DateType::class)
->add('gracePeriod', IntegerType::class)
->add('balance', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
->add('active', CheckboxType::class, ['label' => 'Active', 'data' => true])
->add('save', SubmitType::class, ['label' => 'Save Payee'])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Payee'
));
}
}
Controller:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
class FormController extends Controller
{
/**
* #Route("/_form/entity/{entity}", name="new_entity_form")
* #Method("GET")
*/
public function getFormForNewEntity(Request $request)
{
$rawName = $request->get('entity');
$content = $request->getContent();
$data = json_decode($content, true);
$formName = strtolower($rawName) . "_form";
$submitFunction = $data['submitFunction'];
$entityName = "AppBundle\Entity\\" . $rawName;
$entity = new $entityName();
$form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
return $this->render('form/form.html.twig', [
'name' => $formName,
'form' => $form->createView(),
'submitFunction' => $submitFunction]);
}
/**
* #Route("/_form/entity/{entity}", name="new_entity_create")
* #Method("POST")
*/
public function saveFormForNewEntity(Request $request)
{
$em = $this->getDoctrine()->getManager();
$rawName = $request->get('entity');
$entityName = "AppBundle\Entity\\" . $rawName;
$entity = new $entityName();
$form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
return new JsonResponse(['result' => true]);
} elseif ($form->isEmpty()) {
return new JsonResponse(['result' => false, 'errors' => 'form empty']);
} else {
return new JsonResponse(['result' => false, 'errors' => iterator_to_array($form->getErrors(true))]);
}
}
}
Form twig:
{{ form_start(form, {'attr': {'id':name, 'role':'form', 'submit.delegate':submitFunction}}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Aurelia component js:
import {InlineViewStrategy} from 'aurelia-framework';
import {customElement, bindable, inject} from 'aurelia-framework';
import $ from 'jquery';
import {HttpClient} from 'aurelia-http-client';
import 'fetch';
#customElement('symfony-form')
#inject(Element)
export class SymfonyForm {
#bindable entity;
constructor(element) {
this.content = '';
this.http = new HttpClient();
this.http.configure(config => {
config
.withBaseUrl('http://localhost:8000/');
});
this.element = element;
}
bind(binding, override) {
return this.http.get('_form/entity/' + this.entity, {'submitFunction': 'submit()'})
//.then(response => response.html())
.then(response => {
this.content = response.response;
});
}
submit() {
// application/x-www-form-urlencoded
this.http.createRequest('_form/entity/' + this.entity)
.withHeader('Content-Type', 'application/x-www-form-urlencoded')
.asPost()
.withContent($(this.element).find('form').serialize())
.send()
.then(response => {
alert(response.response);
});
//alert('submitted ' + this.entity);
// return this.http.post('_form/entity/' + this.entity, $(this.element).find('form').serialize())
// .then(response => {
// alert(response.response);
// });
}
}
aurelia component view:
<template>
<form role="form" submit.delegate="submit()">
<div innerHTML.bind="content"></div>
</form>
</template>
aurelia page:
<template>
<require from="form"></require>
<section class="au-animate">
<h2>${heading}</h2>
<form role="form" submit.delegate="submit()">
<div class="form-group">
<label for="fn">First Name</label>
<input type="text" value.bind="firstName" class="form-control" id="fn" placeholder="first name">
</div>
<div class="form-group">
<label for="ln">Last Name</label>
<input type="text" value.bind="lastName" class="form-control" id="ln" placeholder="last name">
</div>
<div class="form-group">
<label>Full Name</label>
<p class="help-block">${fullName | upper}</p>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<symfony-form entity="Payee"></symfony-form>
</section>
</template>
I'm not an expert on SPAs, or JS frameworks, but from what I can see the problem is the lack of a CSFR field with the correct token and also that I don't believe your inputs are named correctly for symphony to read them correctly (I may have missed where this is handled so apologies if so). You need to have the input name formatted as below:
<input type="text" name="formname[formfield]" />
So for example I believe you need your name field to be:
<input type="text" name="payeetype[name]" />

How create file input at form, which upload file and write link in database

I'm trying to learn Yii2 by writing my own cms.
I want realize attachment photo for shop items. I don't know right way to do this, but i think it's should be so -
On save, files which was selected in multiple file input are uploads to server.
Get the url by each photo
Write links in database cell by template
<div class="itemImgs">
<img class="0" src="{link}"> <!-- first -->
<img class="1" src="{link}"> <!-- second -->
<img class="..." src="{link}"> <!-- ... -->
</div>
Please, help me understand, what i must write in model and\or controller, if its right way. Else, please tell me how should to do it.
Thanks.
UPD
Action in controller:
public function actionCreate() {
$model = new ShopItems();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'category' => ShopCategories::find()->all()
]);
}
}
Model contain this functions:
public function behaviors() {
return [
TimestampBehavior::className(),
];
}
/** #inheritdoc */
public static function tableName() {return 'shop_items';}
/** #inheritdoc */
public function rules() {
return [
[['category_id', 'title', 'desc', 'price', ], 'required'],
[['category_id', 'price', 'in_stock', 'discount',], 'integer'],
[['desc', 'options',], 'string'],
[['photos',], 'file', 'maxFiles' => 10],
[['title'], 'string', 'max' => 100]
];
}
/** #inheritdoc */
public function attributeLabels() {
return [
'id' => 'ID',
'category_id' => 'Категория',
'title' => 'Название',
'desc' => 'Описание',
'price' => 'Цена',
'discount' => 'Скидка %',
'in_stock' => 'На складе',
'photos' => 'Фото',
'options' => 'Опции',
'created_at' => 'Дата добавления',
'updated_at' => 'Последнее редактирование',
];
}
And the view _form.php:
<?php $form = ActiveForm::begin(); ?>
<div class="col-lg-6">
<?= $form->field($model, 'title')->textInput(['maxlength' => 100]) ?>
<?= $form->field($model, 'desc')->textarea(['class' => 'ckeditor',]); ?>
</div>
<div class="col-lg-6">
<?= $form->field($model, 'category_id')->dropDownList(
ArrayHelper::map($category, 'category_id', 'category_name')
) ?>
<?= $form->field($model, 'price')->textInput() ?>
<?= $form->field($model, 'discount')->textInput() ?>
<?= $form->field($model, 'in_stock')->textInput() ?>
<?= $form->field($model, 'photos[]')->fileInput(['multiple' => true]) ?>
<?= $form->field($model, 'options')->textInput() ?>
</div>
<div class="clearfix"></div>
<div class="col-xs-12">
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Добавить' : 'Принять изменения', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
See documentation - http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html#uploading-multiple-files
In controller:
if ($model->file && $model->validate()) {
foreach ($model->file as $file) {
$file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
}
}
Input model Photo:
if ($model->file && $model->validate()) {
foreach ($model->file as $file) {
$path = 'uploads/' . $file->baseName . '.' . $file->extension;
$file->saveAs($path);
$photo = new Photo();
$photo->path = $path;
$photo->save();
}
}
Photo table like that:
CREATE TABLE `photo` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`path` VARCHAR(255) NOT NULL ,
`status` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;
Get photos use:
$photos = Photo::find()->all();
In view:
<div class="itemImgs">
<?php foreach ($photos as $k=>$photo) ?>
<img class="<?= $k ?>" src="<?= $photo->path ?>"/><br/>
<?php } ?>
</div>
EDIT
Set in controller
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$files = UploadedFile::getInstances($model, 'file');
$photosArr = [];
foreach ($files as $file) {
$path = 'uploads/' . $file->baseName . '.' . $file->extension;
$file->saveAs($path);
$photosArr[] = $path;
}
$model->photos = Json::encode($photosArr);// better put json in afterSave
$model->save(false);// because validate() run before
return $this->redirect(['view', 'id' => $model->id]);
}
In field photos you get JSON with path for uploaded photos. In view:
$arr = Json::decode($model->photos); // better put in afterFind()
foreach ($arr as $path) {
echo '<img src="'.$path.'">';
}

PDO and OOP login

I'm programming my first website using PDO and OOP right now. I've only used MySQL/ MySQLi and standard PHP before.
I created a login/register system using phpacademy's OOP register/login tutorial series.
Now I have a question about this. How do I add an isOwner or something that I can use to check if the logged in user is on it's own profile etc. I'm going to try creating a pm system and then I need this to make sure that you can't send a pm to yourself :)
Here's the code:
login.php
<?php
require_once 'core/init.php';
$user = new User();
if ($user->isLoggedIn()) {
Redirect::to('index.php');
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Log in</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="style/global.css">
<link rel="stylesheet" type="text/css" href="css/font-awesome.css">
<script src="js/main.js"></script>
</head>
<body>
<?php require_once 'includes/header.php'; ?>
<form action="" method="post">
<h1>Log in</h1>
<div class="inset">
<?php
if (input::exists()) {
if (Token::check(Input::get('token'))) {
$validate = new Validate();
$validation = $validate->check($_POST, array(
'username' => array(
'required' => true,
'name' => 'Username'
),
'password' => array(
'required' => true,
'name' => 'Password'
)
));
if ($validation->passed()) {
$user = new User();
$remember = (Input::get('remember') === 'on') ? true : false;
$login = $user->login(Input::get('username'), Input::get('password'), $remember);
if ($login) {
Redirect::to('index.php');
} else {
echo '<p>Sorry, logging in failed </p>';
}
} else {
foreach ($validation->errors() as $error) {
echo '<i class="fa fa-exclamation-triangle"></i> ', $error, '<br>';
echo '<br />';
}
}
}
}
?>
<p>
<label for="username">USERNAME</label>
<input type="text" name="username" id="username" value="<?php echo escape(Input::get('username')); ?>">
</p>
<p>
<label for="password">PASSWORD</label>
<input type="password" name="password" id="password">
</p>
<p>
<input type="checkbox" name="remember" id="remember">
<label for="remember">Remember me for 1 month</label>
</p>
</div>
<input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
<p class="p-container">
<span>Forgot password?</span>
<input type="submit" name="go" id="go" value="Log in">
</p>
</form>
</body>
</html>
Validate.php
<?php
class Validate {
private $_passed = false,
$_errors = array(),
$_db = null;
public function __construct() {
$this->_db = DB::getInstance();
}
public function check($source, $items = array()) {
foreach ($items as $item => $rules) {
foreach ($rules as $rule => $rule_value) {
$value = trim($source[$item]);
$item = escape($item);
if ($rule === 'required' && empty($value)) {
$this->addError("{$rules['name']} is required");
} else if(!empty($value)) {
switch ($rule) {
case 'min':
if (strlen($value) < $rule_value) {
$this->addError("{$rules['name']} must be a minimum of {$rule_value} characters.");
}
break;
case 'max':
if (strlen($value) > $rule_value) {
$this->addError("{$rules['name']} must be a maximum of {$rule_value} characters.");
}
break;
case 'matches':
if ($value != $source[$rule_value]) {
$this->addError("{$rule_value} must match {$rules['name']}");
}
break;
case 'unique':
$check = $this->_db->get($rule_value, array($item, '=', $value));
if ($check->count()) {
$this->addError("{$rules['name']} already exists.");
}
break;
}
}
}
}
if (empty($this->_errors)) {
$this->_passed = true;
}
return $this;
}
private function addError($error) {
$this->_errors[] = $error;
}
public function errors() {
return $this->_errors;
}
public function passed() {
return $this->_passed;
}
}
User.php
<?php
class User {
private $_db,
$_data,
$_sessionName,
$_cookieName,
$_isLoggedIn;
public function __construct($user = null) {
$this->_db = DB::getInstance();
$this->_sessionName = Config::get('session/session_name');
$this->_cookieName = Config::get('remember/cookie_name');
if (!$user) {
if (Session::exists($this->_sessionName)) {
$user = Session::get($this->_sessionName);
if ($this->find($user)) {
$this->_isLoggedIn = true;
} else {
// process logout
}
}
} else {
$this->find($user);
}
}
public function update($fields = array(), $id = null) {
if (!$id && $this->isLoggedIn()) {
$id = $this->data()->id;
}
if (!$this->_db->update('users', $id, $fields)) {
throw new Exception('There was a problem updating');
}
}
public function create($fields = array()) {
if (!$this->_db->insert('users', $fields)) {
throw new Exception('There was a problem creating an account.');
}
}
public function find($user = null) {
if ($user) {
$field = (is_numeric($user)) ? 'id' : 'username';
$data = $this->_db->get('users', array($field, '=', $user));
if ($data->count()) {
$this->_data = $data->first();
return true;
}
}
return false;
}
public function login($username = null, $password = null, $remember = false) {
if (!$username && !$password && $this->exists()) {
Session::put($this->_sessionName, $this->data()->id);
} else {
$user = $this->find($username);
if ($user) {
if ($this->data()->password === Hash::make($password, $this->data()->salt)) {
Session::put($this->_sessionName, $this->data()->id);
if ($remember) {
$hash = Hash::unique();
$hashCheck = $this->_db->get('users_session', array('user_id', '=', $this->data()->id));
if (!$hashCheck->count()) {
$this->_db->insert('users_session', array(
'user_id' => $this->data()->id,
'hash' => $hash
));
} else {
$hash = $hashCheck->first()->hash;
}
Cookie::put($this->_cookieName, $hash, Config::get('remember/cookie_expiry'));
}
return true;
}
}
}
return false;
}
public function hasPermission($key) {
$group = $this->_db->get('groups', array('id', '=', $this->data()->group));
if ($group->count()) {
$permissions = json_decode($group->first()->permissions, true);
if ($permissions[$key] == true) {
return true;
}
}
return false;
}
public function exists() {
return (!empty($this->_data)) ? true : false;
}
public function logout() {
$this->_db->delete('users_session', array('user_id', '=', $this->data()->id));
Session::delete($this->_sessionName);
Cookie::delete($this->_cookieName);
}
public function data() {
return $this->_data;
}
public function isLoggedIn() {
return $this->_isLoggedIn;
}
}
Could someone please help me with this?
Thanks in advance,
Busarna