Update doesn't working using doctrine - doctrine

I want to update all my events having the same name by updating start and end dates ,
I have posted the question before but now I have changed some of the code but still not working ?
the code redirect to app_event route without updating !!
Where is the error ?
Controller.php :
public function updateEventsAction(Request $request )
{
$form = $this->createForm('AppBundle\Form\UpdateEventType');
$form->handleRequest($request);
$event_name=$form[name]->getData();
$choosedName = $event_name->getName(); //get name from combobox
$em = $this->getDoctrine()->getManager();
$repository = $this
->getDoctrine()
->getManager()
->getRepository('AppBundle:Event')
;
$events = $repository->findBy(
array('name' => $choosedName) // array of events have same name choosen from combobox
);
if ($form->isSubmitted() && $form->isValid()) {
//foreach event update start and end dates
foreach ($events as $event) {
$event ->setStartDate($event ->getStartDate ());
$event ->setEndDate($event ->getEndDate ());
$em->persist($event);
$em->flush();
}
return $this->redirectToRoute(‘app_event’);
}
return $this->render('AppBundle:Event:updateEvents.html.twig', array(
'form' => $form->createView(),
));
}
Event.html.twig
{{ form_start(form}}
<div>
<label for="name">Name of the event</label>
<div > {{ form_widget(form.name}} </div>
</div>
<div >
<label for="startDate ">Start date </label>
<div > {{ form_widget(form.startDate }} </div>
</div>
<div>
<label for=" EndDate ">End date </label>
<div> {{ form_widget(form. endDate}} </div>
</div>
<div>
<button type="submit" ">Update</button>
</div>
</div>
{{ form_end(form) }}
UpdateEventsType.php :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(' name ',EntityType::class,array(
'class' => 'AppBundle: Event', 'choice_label'=>'name') )
->add(' startDate ', DateType::class, array(
'widget' => 'single_text',
// this is actually the default format for single_text
'format' => 'yyyy-MM-dd'))
->add(' endDate ', DateType::class, array(
'widget' => 'single_text',
// this is actually the default format for single_text
'format' => 'yyyy-MM-dd'))
;
}
Update
Now I have updated my code it seems a date format problem because after updating my code this is the error:
An exception occurred while executing 'UPDATE event SET startDate = '$ choosedStartDate ', endDate = '$ choosedEndDate ' WHERE name = ?' with params ["Events16"]:
SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect date value: '$choosedDateDebut' for column startDate at row 1
This is the new code
public function updateEventsAction(Request $request )
{
$form = $this->createForm('AppBundle\Form\UpdateEventType');
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event_name=$form['name']->getData();
$choosedName = $event_name->getName();
$choosedStartDate=$form[startDate]->getData();
$choosedEndDate =$form[endDate]->getData();
print_r("***********choosed Start date****************"); print_r($choosedStartDate);
print_r("***********choosed end date****************"); print_r($choosedEndDate
$em = $this->getDoctrine()->getManager();
$repository = $this
->getDoctrine()
->getManager()
->getRepository('AppBundle:Event)
;
$listevents= $repository->findBy(
array('name' => $choosedName) // Critere
);
foreach ($listevents as $event) {
$datestart_bd =$event->getDateDebut();
print_r("Start date from database");
print_r($datestart _bd);
}
$q = $em->createQuery('update AppBundle\Entity\Event e SET e.startDate =\'$choosedStartDate \' , e.endDate =\'$choosedEndDate \' WHERE e.name= ?1' );
$q->setParameter(1, $choosedName);
$q->execute();
return $this->redirectToRoute('app_event');
}
return $this->render('AppBundle:Event:updateEvents.html.twig', array(
'form' => $form->createView(),
));
}
Update2
Now the code work fine I am not using createQuery anymore
my code working:
public function updateEventsAction(Request $request )
{
$form = $this->createForm('AppBundle\Form\UpdateEventType');
$form->handleRequest($request);
$event_name=$form[name]->getData();
$choosedName = $event_name->getName(); //get name from combobox
$choosedStartDate=$form[‘startDate’]->getData();
$choosedEndDate =$form[‘endDate’]->getData();
$em = $this->getDoctrine()->getManager();
$repository = $this
->getDoctrine()
->getManager()
->getRepository('AppBundle:Event')
;
$events = $repository->findBy(
array('name' => $choosedName) // array of events have same name choosen from combobox
);
if ($form->isSubmitted() && $form->isValid()) {
//foreach event update start and end dates
foreach ($events as $event) {
$event ->setStartDate($choosedStartDate)
$event ->setEndDate($choosedEndDate);
$em->flush();
}
return $this->redirectToRoute(‘app_event’);
}
return $this->render('AppBundle:Event:updateEvents.html.twig', array(
'form' => $form->createView(),
));
}

You are setting same dates to the events as you take them from database, when you probably want to set them from form.
Change this code fragment:
foreach ($events as $event) {
//$event_name variable holds your form data
$event->setStartDate($event_name->getStartDate());
$event->setEndDate($event_name->getEndDate());
$em->persist($event);//note that you only need to persist new events, so this is unnecesarry
$em->flush();//I'd recommend 'batch' flushes
}
More info on batch processing.

Related

Laravel: how can i get files from database in edit form. so i dont have to reupload if i dont want to change the files

blade edit
<form action="/files" method="POST" enctype="multipart/form-data">
{{csrf_field()}}
<label for="dokumen">Dokumen Awal : ({{$aktivitas_list->dokumen}}) <br><i>Upload Ulang Dokumen</i></label>
<input type="file" id="dokumen" name="dokumen" accept=".pdf" class="form-control" value="{{$aktivitas_list->dokumen}}">
#if ($errors->has('dokumen'))
<span class="text-danger">{{ $errors->first('dokumen') }}</span>
#endif
controller store
$aktivitas_list = new Aktivitas;
$aktivitas_list->pt_id = $request->get('pt_id');
$aktivitas_list->nama_aktivitas = $request->get('nama_aktivitas');
$aktivitas_list->tgl_aktivitas = $request->get('tgl_aktivitas');
$aktivitas_list->tempat = $request->get('tempat');
$aktivitas_list->jenis_aktivitas = $request->get('jenis_aktivitas');
$aktivitas_list->dokumen = $request->file('dokumen');
$aktivitas_list->tenggat_waktu = $request->get('tenggat_waktu');
$aktivitas_list->deskripsi = $request->get('deskripsi');
$aktivitas_list->status = $request->get('status');
$aktivitas_list->user = $request->get('user');
$rules = array(
'nama_aktivitas' => 'required',
'dokumen' => 'required|mimes:pdf'
);
$dokumen = $request->file('dokumen');
$tujuan_upload = 'document-upload';
$dokumen->move($tujuan_upload, $dokumen->getClientOriginalName());
$aktivitas_list->dokumen = $dokumen->getClientOriginalName();
if ($aktivitas_list->save()) {
return redirect('pt')->with('success', 'Data Berhasil Ditambahkan');
} else {
return redirect('pt')->with('error', 'error message');
}
}
controller update
$rules = array(
'nama_aktivitas' => 'required',
'dokumen' => 'required|mimes:pdf'
);
$dokumen = $request->file('dokumen');
$tujuan_upload = 'document-upload';
$dokumen->move($tujuan_upload, $dokumen->getClientOriginalName());
$aktivitas_list->dokumen = $dokumen->getClientOriginalName();
$aktivitas_list->status = $status=1;
$aktivitas_list->user = Auth::user()->name;
$user = Auth::user()->name;
if ($aktivitas_list->save()) {
return redirect('pt')->with('success', 'Data Berhasil Ditambahkan');
} else {
return redirect('pt')->with('error', 'error message');
}
The problem is, if I don't select again the file when I update the data so the data is null. for example i just want to edit field nama aktivitas and not change the files. and another example i want to update all field. how can i get the files beside the browse button? how can i solve them? please guys help me
In Controller on update method
Make file as optional.
Check if request has file then make process of upload.
in view you can't set file input value for security reason.
$rules = array(
'nama_aktivitas' => 'required',
'dokumen' => 'nullable|mimes:pdf'//make file as optional
);
if($request->file('dokumen')){//check if file are exists on request
$dokumen = $request->file('dokumen');
$tujuan_upload = 'document-upload';
$dokumen->move($tujuan_upload, $dokumen->getClientOriginalName());
$aktivitas_list->dokumen = $dokumen->getClientOriginalName();
}
$aktivitas_list->status = $status=1;
$aktivitas_list->user = Auth::user()->name;
$user = Auth::user()->name;
if ($aktivitas_list->save()) {
return redirect('pt')->with('success', 'Data Berhasil Ditambahkan');
} else {
return redirect('pt')->with('error', 'error message');
}
you can check if file existed then upload it and save file's new name in database and if file didn't exist just escape this field so old value remain in database.
if($request->hasFile()) {
}
See docs here
public function update(Request $request)
{
$rules = array(
'nama_aktivitas' => 'required',
'dokumen' => 'sometimes|mimes:pdf'
);
//Validation of request data
if($request->hasFile('dokumen') && $request->file('dokumen')->isValid()){
$dokumen = $request->file('dokumen');
$tujuan_upload = 'document-upload';
$dokumen->move($tujuan_upload, $dokumen->getClientOriginalName());
//Since your provided code snippet for update is truncated
// don't know how $aktivitas_list is instantiated
$aktivitas_list->dokumen = $dokumen->getClientOriginalName();
}
$aktivitas_list->status = $status=1;
$aktivitas_list->user = Auth::user()->name;
$user = Auth::user()->name;
if ($aktivitas_list->save()) {
return redirect('pt')->with('success', 'Data Berhasil Ditambahkan');
} else {
return redirect('pt')->with('error', 'error message');
}
}

Codeigniter-login with session

i am trying to do a login with sessions but it doesn't seem to be working because when i log in the session data on the view is not being displayed. once logged in it should read something like: 'Welcome Jon' but it doesn't. What could be the issue
controller fn
function login_user()
{
if(isset($_POST['login']))
{
$data = $this->Model_students->fetchUserData();
if(!empty($data))
{
var_dump($data);
foreach ($data as $key => $value) :
$user_id = $value->id;
$firstname = $value->firstname;
$lastname = $value->lastname;
$grade = $value->grade;
$email = $value->email;
$images = json_decode($value->userfile);
endforeach;
$user_info = array(
'id' => $user_id,
'firstname' => $firstname,
'lastname' => $lastname,
'grade' => $grade,
'email' => $email,
'images' => $images[0]->file_name,
'is_logged_in' => TRUE
);
$this->session->set_userdata($user_info);
redirect('Students/homepage');
}
else
{
$this->session->set_flashdata('error', 'Error! Invalid username or password');
redirect('Students/login_user');
}
}
else
{
$this->load->view('signup');
}
}
model
the join here is for a different table in the same db where the common row is id..not sure if the join is correct too
public function fetchUserData()
{
$this->db->select('users.*, user_images.*');
$this->db->from('users');
$this->db->join('user_images', 'users.id=user_images.user', 'inner');
$this->db->where('email', $this->input->post('email'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get();
if($query->num_rows() == 1 ) :
foreach($query->result() as $row):
$data[] = $row;
endforeach;
return $data;
endif;
}
view the img scr here should display the user image based on what is saved on the db when he/she first registered
</head>
<body>
<h3>Welcome <?php $this->session->userdata('$firstname')?>.</h3>;
<img class ="img-circle" src="<?=base_url();?>uploads/users/<?=$this->session->userdata('userfile/file_name');?>" width="250" height="auto">
There's a typo in your views. where the session variable should be without the $ symbol.
<h3>Welcome <?php echo $this->session->userdata('firstname'); ?>.</h3>;
Also, check if the $user_info contains the expected data. Do a var_dump($user_info) and see just before creating the session.
there could be many issues with it.
1: your are passing a variable in the string which is not valid ( $this->session->userdata('$firstname') ) remove the $ from the first name;
2: there has to be a constructor in the controller so that the session could be called when ever the object is created;
hope it will solve your problem

getMimeType() before moving file in Laravel

This a part of my app I'm using to put a section that admin can choose the category of the file from...
File Model
namespace App\Models;
use App\Traits\Categorizeable;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
use Categorizeable;
protected $primaryKey = 'file_id';
protected $guarded = ['file_id'];
public function packages()
{
return $this->belongsToMany(Package::class, 'package_file');
}
}
Anyway I used a trait for it...
after that it is my view:
<div class="form-group">
<label for="categorize"> categories :</label>
<select name="categorize[]" id="categorize" class="select2 form-control" multiple>
#foreach($categories as $cat)
<option value="{{$cat->category_id}}"
{{isset($file_categories) && in_array($cat->category_id,$file_categories) ? 'selected' :'' }}>
{{$cat->category_name}}</option>
#endforeach
</select>
</div>
at last this is my FilesController:
public function store(Request $request)
{
// $this->validate();....
//after validation
$new_file_name = str_random(45) . '.' . $request->file('fileItem')->getClientOriginalExtension();
$result = $request->file('fileItem')->move(public_path('files'), $new_file_name);
if ($result instanceof \Symfony\Component\HttpFoundation\File\File) {
$new_file_data['file_name'] = $new_file_name;
$new_file_data = File::create([
'file_title' => $request->input('file_title'),
'file_description' => $request->input('file_description'),
'file_type' => $request->file('fileItem')->getMimeType(),
'file_size' => $request->file('fileItem')->getClientSize(),
]);
if ($new_file_data) {
if ($request->has('categorize')) {
$new_file_data->categories()->sync($request->input('categorize'));
}
return redirect()->route('admin.files.list')->with('success', 'message');
}
}
}
Now what my problem is that as you see file() saves a .tmp file first and I need to use getMimeType() before I move it, how to modify my code?
What is the best way to do that?
App is giving me an Error
Save the mime type as a variable before you move the file and use it in the create function
$new_file_name = str_random(45) . '.' . $request->file('fileItem')->getClientOriginalExtension();
$mime_type = $request->file('fileItem')->getMimeType();
$file_size = $request->file('fileItem')->getClientSize();
$result = $request->file('fileItem')->move(public_path('files'), $new_file_name);
if ($result instanceof \Symfony\Component\HttpFoundation\File\File) {
$new_file_data['file_name'] = $new_file_name;
$new_file_data = File::create([
'file_title' => $request->input('file_title'),
'file_description' => $request->input('file_description'),
'file_type' => $mime_type,
'file_size' => $file_size,
]);

Laravel 5.7 - Pivot table attach()

I cannot get attach() to work in my setup.
Each User can have many Orders which can have many Products.
User.php
public function orders()
{
return $this->hasMany(Order::class);
}
Order.php
public function users()
{
return $this->belongsTo(User::class);
}
public function products()
{
return $this->belongsToMany(Product::class)
->withTimestamps()
->withPivot('qty');
}
Product.php
public function orders()
{
return $this->belongsToMany(Order::class)
->withTimestamps()
->withPivot('qty');
}
I have a create.blade.php which is meant to show all available products and the quantity for each can be chosen, this is to be saved on the pivot table.
create.blade.php
{{ Form::open(array('url' => '/orders/store')) }}
#foreach ($products as $product)
<div>
<span class="mealname">{{ $product->name }}</span>
<hr>
<p>{{ $product->description }}</p>
</div>
<div class="qty">
{{ Form::text( 'qty', 0, [ 'type' => 'tel' ]) }}
</div>
#endforeach
{{ Form::select('delivery_day', ['M' => 'Monday', 'W' => 'Wednesday'],
null, ['placeholder' => 'Delivery Day'])
}}
{{ Form::submit('Place Order') }}
{{ Form::close() }}
When I submit the request only the fields to the Order table are saved,
public function store(Request $request)
{
// Validate
$request->validate([
'qty'=> 'integer',
]);
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
// passed in parameters of form (not qty)
auth()->user()->orders()->save($order); // save order
# Pivot attach()
HERE I AM LOST
return redirect('complete')->with('success', 'Order has been created');
}
I believe it is the fact that I am trying to pass multiple products in one form, (which I believe i should be able to just pass as an arry while I use attach().
I have tried various solutions and I am still unable to ever get the pivot table to populate.
My last attempt was to pass the product_id through a hidden field and then running this.
$attach_data = [];
for ($i = 0; $i < count($product_ids); $i++);
$attach_data[$product_ids[$i]] = ['qty' => $qtys[$i]];
$order->product_ids()->attach($attach_data);
However, this did not work.
According to the docs (https://laravel.com/docs/5.7/eloquent-relationships#updating-many-to-many-relationships) this is one way to attach multiple items:
$user->roles()->attach([
1 => ['expires' => $expires],
2 => ['expires' => $expires]
]);
So you have to modify this:
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
$order->save();
// change this for your array of ids
$products_to_sync_ids = [1,3,23];
$sync_data = [];
$qty = 1; <----- I dont know if you are inserting them with the same qty
for($i = 0; $i < count($products_to_sync_ids); $i++))
$sync_data[$products_to_sync_ids[$i]] = ['qty' => $qty];
$order->products()->sync($sync_data);
Try and check if the products are inserting correctly on the pivot table and then modify the code to insert every code with his quantity.

CakePHP 3.1 : My validation for translate behaviour fields, need some help in review/comment

I have worked on a hook for validate my translated fields, based on this thread : https://stackoverflow.com/a/33070156/4617689. That i've done do the trick, but i'm looking for you guys to help me to improve my code, so feel free to comment and modify
class ContentbuildersTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree');
$this->addBehavior('Timestamp');
$this->addBehavior('Translate', [
'fields' => [
'slug'
]
]);
}
public function validationDefault(Validator $validator)
{
$data = null; // Contain our first $context validator
$validator
->requirePresence('label')
->notEmpty('label', null, function($context) use (&$data) {
$data = $context; // Update the $data with current $context
return true;
})
->requirePresence('type_id')
->notEmpty('type_id')
->requirePresence('is_activated')
->notEmpty('is_activated');
$translationValidator = new Validator();
$translationValidator
->requirePresence('slug')
->notEmpty('slug', null, function($context) use (&$data) {
if (isset($data['data']['type_id']) && !empty($data['data']['type_id'])) {
if ($data['data']['type_id'] != Type::TYPE_HOMEPAGE) {
return true;
}
return false;
}
return true;
});
$validator
->addNestedMany('translations', $translationValidator);
return $validator;
}
}
I'm not proud of my trick with the $data, but i've not found a method to get the data of the validator into my nestedValidator...
Important part here is to note that i only rule of my nestedValidator on 'translations', this is very important !
class Contentbuilder extends Entity
{
use TranslateTrait;
}
Here basic for I18ns to work
class BetterFormHelper extends Helper\FormHelper
{
public function input($fieldName, array $options = [])
{
$context = $this->_getContext();
$explodedFieldName = explode('.', $fieldName);
$errors = $context->entity()->errors($explodedFieldName[0]);
if (is_array($errors) && !empty($errors) && empty($this->error($fieldName))) {
if (isset($errors[$explodedFieldName[1]][$explodedFieldName[2]])) {
$error = array_values($errors[$explodedFieldName[1]][$explodedFieldName[2]])[0];
$options['templates']['inputContainer'] = '<div class="input {{type}} required error">{{content}} <div class="error-message">' . $error . '</div></div>';
}
}
return parent::input($fieldName, $options);
}
}
With that formHelper we gonna get the errors of nestedValidation and inject them into the input, i'm not confortable with the templates, so that's why it's very ugly.
<?= $this->Form->create($entity, ['novalidate', 'data-load-in' => '#right-container']) ?>
<div class="tabs">
<?= $this->Form->input('label') ?>
<?= $this->Form->input('type_id', ['empty' => '---']) ?>
<?= $this->Form->input('is_activated', ['required' => true]) ?>
<?= $this->Form->input('translations.fr_FR.slug') ?>
<?= $this->Form->input('_translations.en_US.slug') ?>
</div>
<?php
echo $this->Form->submit(__("Save"));
echo $this->Form->end();
?>
Here my fr_FR.slug is required when type_id is not set to Type::TYPE_HOMEPAGE, yeah my homepage has not slug, note that the en_US.slug is not required at all, because i only required 'translations.xx_XX.xxxx' and not '_translations.xx_XX.xxxx'.
And the last part of the code, the controller
$entity = $this->Contentbuilders->patchEntity($entity, $this->request->data);
// We get the locales
$I18ns = TableRegistry::get('I18ns');
$langs = $I18ns->find('list', [
'keyField' => 'id',
'valueField' => 'locale'
])->toArray();
// Merging translations
if (isset($entity->translations)) {
$entity->_translations = array_merge($entity->_translations, $entity->translations);
unset($entity->translations);
}
foreach ($entity->_translations as $lang => $data) {
if (in_array($lang, $langs)) {
$entity->translation($lang)->set($data, ['guard' => false]);
}
}
Here a .gif of the final result om my side : http://i.giphy.com/3o85xyrLOTd7q0YVck.gif

Resources