I'm working on project, I faced some problems
If I fill all fields and then submit there is no problem and it saved to database, but my issue if some field is empty the validation messages error appear in another page as JSON format.
I don't use any AJAX code in my view file.
Here is controller code:
public function store(RegisterRequest $request){
$user = User::create($request->all());
$user->password = Hash::make($request['password']);
if ($request->file('avatar')) {
$image = $request->file('avatar');
$destinationPath = base_path() . '/public/uploads/default';
$path = time() . '_' . Str::random(10) . '.' . $image->getClientOriginalExtension();
$image_resize = Intervention::make($image->getRealPath());
$image_resize->resize(300, 300);
$image_resize->save($destinationPath . '/' . $path);
} else {
$path = $user->avatar;
}
$user->avatar = $path;
$user->save();
return redirect()->route('admin.user.index')->with('message','User created successfully');
And here is RegisterRequest code:
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:6|confirmed',
'country_code' => 'sometimes|required',
'phone'=>Rule::unique('users','phone')->where(function ($query) {
$query->where('country_code', Request::get('country_code'));
})
];
Can you help me please?
Your errors should be accessible inside blade file with $errors variable which you need to iterate and display the errors.
Link to doc which will help you with the render part - https://laravel.com/docs/7.x/validation#quick-displaying-the-validation-errors
Clearly from doc as well
If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.
https://laravel.com/docs/7.x/validation#creating-form-requests
Also refactor the code a bit as following to run only one query to create a user instead of creating and then updating.
public function store(RegisterRequest $request){
if ($request->hasFile('avatar')) {
//use try catch for image conversion might be a rare case of lib failure
try {
$image = $request->file('avatar');
$destinationPath = base_path() . '/public/uploads/default';
$path = time() . '_' . Str::random(10) . '.' . $image->getClientOriginalExtension();
$image_resize = Intervention::make($image->getRealPath());
$image_resize->resize(300, 300);
$image_resize->save($destinationPath . '/' . $path);
$request->avatar = $path;
} catch(\Exception $e){
//handle skip or report error as per your case
}
}
$request['password'] = Hash::make($request['password']);
$user = User::create($request->all());
return redirect()->route('admin.user.index')->with('message','User created successfully');
}
I am creating Laravel 7 project and I want to add/browse images into/from MySQL database.
The images column names are icon_lg and icon_sm
This is my create function in the Controller I tried it in two ways as I saw in some tutorials:
public function create(Request $request)
{
$object = $this->objectModel::create([
'name' => $request->name,
'icon_sm' => $request->icon_sm
]);
if($request->hasFile('icon_lg')) {
$images = explode(',', $request->hasFile('icon_lg'));
foreach($images as $image)
$filename = rand().'.'.$image->getClientOriginalExtension();
$filePath = public_path("images");
$image->move($filePath, $filename);
return Image::create([
'icon_lg' => $filename,
//'item_id' => $created->id,
]);
}
if ($request->save == 'browse')
return redirect()->route("{$this->objectName}");
elseif ($request->save == 'edit')
return redirect()->route("{$this->objectName}.edit", ['id' => $object]);
elseif ($request->save == 'add')
return redirect()->route("{$this->objectName}.add");
else
return redirect($request->previous_url);
}
It does nothing with icon_lg it inserts null value to it.
And it deals with icon_sm as String.
i think you must set the hasfile validation inside foreach loop like
$images = explode(',', $request->hasFile('icon_lg'));
foreach($images as $image)
if($request->hasFile('icon_lg')) {
$filename = rand().'.'.$image->getClientOriginalExtension();
$filePath = public_path("images");
$image->move($filePath, $filename);
return Image::create([
'icon_lg' => $filename,
//'item_id' => $created->id,
]);
}
just test it without validation first
it should work
Following code just uploads one file instead several files.
Any ideas, how to fix that?
Here is my model:
<?php
//Code programmed by Thomas Kipp
//Change it, learn it, do as u please!
///path:/models/
namespace frontend\models;
use Yii;
use yii\base\Model;
class myScriptForm extends Model{ // A new Class programmed by Thomas Kipp
...
public $avatar;
...
public function rules() {
$avatar=array();
return [
['avatar[]','file']]
}
}
//End of class
?>
Here is my method of SiteController:
public function actionScript() { //A new method, programmed by Thomas Kipp
$model = new myScriptForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->avatar = UploadedFile::getInstances($model, 'avatar[]');
if ($model->avatar) {
echo "<font size='4'><br><center>File <font color='red'> "
. "$model->avatar<font color='black'> successfully uploaded."
. "<br>It's available in folder 'uploadedfiles' </font></font color></center>";
$model->avatar->saveAs(Yii::getAlias('#uploadedfilesdir/' . $model->avatar->baseName . '.' . $model->avatar->extension));
} else
echo"<font size='4'><br><center>No Upload-file selected.<br>"
. "Nothing moved into folder 'uploadedfiles' </font></center>";
return $this->render('myScript', ['model' => $model]);
}
else {
return $this->render('myScript_Formular', ['model' => $model]);
}
}
and still my Formular, which is not uploading several files:
<?=
$form->field($model,'avatar[]')->widget(FileInput::classname(), ['options' => ['accept' => 'image/*', 'multiple' => true],])
?>
First of all, if you have something like echo (...) in controller - youre doing something wrong.
In your code youre not doing any foreach over uploaded files, so it's saving only one.
Yii2 - Uploading Multiple Files - here you have full guide how to upload multiple files, with examples etc.
Below code works for me, hope this will help you,
View file =>
<?= $form->field($model, 'image_files[]')->fileInput(['multiple' => true,'accept' => 'image/*']) ?>
Controller =>
$imagefiles = UploadedFile::getInstances($model, 'image_files');
$model->image_files = (string)count($imagefiles);
if (!is_null($imagefiles)) {
$dirpath = dirname(getcwd());
foreach ($imagefiles as $file) {
$productimage = new ProductImages();
$productimage->image_name = '/admin/uploads/'.$file->baseName.'.'.$file->extension;
$productimage->product_id = $model->id;
if ($productimage->save()) {
$file->saveAs($dirpath . '/admin/uploads/' . $file->baseName . '.' . $file->extension);
}
}
}
i would like to output dynamic generated html content instead of the translatable message but i can't make it work:
function custom_logo_module_block_view($delta = '') {
// don't worry about switch($delta) logic
// perform some operations and then display some generated html
// (maybe use the template(...) function)
// works fine but i'd like to print html
$block['content'] = t('No content available.');
return $block;
}
how can i print out generated html into a block?
i can't find any solutions or code examples. i think i might be pointing towards the wrong direction so best practice suggestions are welcome.
function custom_logo_module_block_view($delta = '') {
$block = array();
if ($delta == 'example') {
$block = array(
'subject' => t('Active users list'),
'content' => example_block_content()
);
}
return $block;
}
function example_block_content() {
// Query for active users from database
$users = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->condition('u.status', 1)
->execute()
->fetchAll();
// Prepare items for item list
$items = array();
foreach ($users as $user) {
$items[] = l($user->name, "user/{$user->uid}");
}
$output = t('No active users available.');
if (!empty($items)) {
$output = theme('item_list', array('items' => $items));
}
return $output;
}
Update regarding your comments...
As far as I understand by some result you mean generated data from database. In this case you can try something like this:
function example_block_content() {
// Query for active users from database
$users = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->condition('u.status', 1)
->execute()
->fetchAll();
$output = '';
foreach ($users as $user) {
$output.= '<div>'. $user->name .'</div>';
}
$output = "<div>Hello World". $output ."</div>";
return $output;
}
This will give you the following output:
<div>Hello World
<div>admin</div>
<div>ndrizza</div>
<div>Vlad Stratulat</div>
...
</div>
Or you can try:
function custom_logo_module_block_view($delta = '') {
$block = array();
if ($delta == 'example') {
$block = array(
'subject' => t('Active users list'),
// this will return "Hello World + some result" text inside <div>
'content' => "<div>Hello World + some result</div>"
);
}
return $block;
}
Both of this ways are working but they are not the right ways. The right way to generate content is in my first answer. Read more about theming in Drupal.
I'm making a "Download" controller using Symfony 2, that has the sole purpose of sending headers so that I can force a .csv file download, but it isn't working properly.
$response = new Response();
$response->headers->set('Content-Type', "text/csv");
$response->headers->set('Content-Disposition', 'attachment; filename="'.$fileName.'"');
$response->headers->set('Pragma', "no-cache");
$response->headers->set('Expires', "0");
$response->headers->set('Content-Transfer-Encoding', "binary");
$response->headers->set('Content-Length', filesize($fileName));
$response->prepare();
$response->sendHeaders();
$response->setContent(readfile($fileName));
$response->sendContent();
$fileName is a "info.csv" string. Such are my actions inside my controller, there's no return statement. When I tried returning the Response Object, the contents of the file were displayed in the browser, not my intended result.
The problem I've found is that in some pages I do get my info.csv file, but in anothers all I get is a message:
No webpage was found for the web address: http://mywebpage.com/download
Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.
I'm completely sure the file exists, so there must be another thing wrong. Also, routing.yml is working correctly, since I do get the file from other pages that also link to that path.
The Apache error log doesn't show anything about it.
Has anyone forced the download of a .csv file on Symfony 2 before? If so, what am I doing wrong?
Here is a minimal example that works just fine in production:
class MyController
public function myAction()
$response = $this->render('ZaysoAreaBundle:Admin:Team/list.csv.php',$tplData);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="teams.csv"');
return $response;
You can replace the render call with new response and response->setContent if you like.
Your comment about no return statement inside a controller is puzzling. Controllers return a response. Let the framework take care of sending the stuff to the browser.
I realize this post is kind of old and that there is, oddly enough, practically no good resources on how to do a CSV Export in symfony 2 besides this post at stackoverflow.
Anyways I used the example above for a client contest site and it worked quite well. But today I received an e-mail and after testing it myself, the code had broken - I was able to get the download working with a small amount of results, but the database now exporting over 31,000 rows it either simply showed the text or with chrome, just basically did nothing.
For anyone having issue with a large data export, this is what I manged to get to work, basically doing what Cerad suggested as an alternate way:
$filename = "export_".date("Y_m_d_His").".csv";
$response = $this->render('AppDefaultBundle:Default:csvfile.html.twig', array('data' => $data));
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Description', 'Submissions Export');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', '0');
$response->prepare();
$response->sendHeaders();
$response->sendContent();
EDIT: After more testing and upping the max seconds allowed, I realized the previous code was printing out the headers at the top so I've updated the code.
THis worked for me to export CSV and JSON.
Twig files are named : export.csv.twig, export.json.twig
The Controller :
class PrototypeController extends Controller {
public function exportAction(Request $request) {
$data = array("data" => "test");
$format = $request->getRequestFormat();
if ($format == "csv") {
$response = $this->render('PrototypeBundle:Prototype:export.' . $format . '.twig', array('data' => $data));
$filename = "export_".date("Y_m_d_His").".csv";
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
return $response;
} else if ($format == "json") {
return new Response(json_encode($data));
}
}
}
The Routing :
prototype_export:
pattern: /export/{_format}
defaults: { _controller: PrototypeBundle:Prototype:export, _format: json }
requirements:
_format: csv|json
The Twigs:
export.csv.twig (do your comma seperated thing here, this is just a test)
{% for row in data %}
{{ row }}
{% endfor %}
export.json.twig (data is sent json_encoded, this file is empty)
Hope this helps!
This is how I managed to get Silex to return a csv:
// $headers in an array of strings
// $results are the records returned by a PDO query
$stream = function() use ($headers, $results) {
$output = fopen('php://output', 'w');
fputcsv($output, $headers);
foreach ($results as $rec)
{
fputcsv($output, $rec);
}
fclose($output);
};
return $app->stream($stream, 200, array(
'Content-Type' => 'text/csv',
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename="test.csv"',
'Expires' => '0',
'Cache-Control' => 'must-revalidate',
'Pragma' => 'public',
));
You may also need to do some Jiggery Pokery with Javascript (I was downloading Via AJAX) but this post was all I needed to get it working.
simple function you can use for every case to export an csv for download...
public function getResponse(array $data, $filename, $headers = array())
{
if(substr(strtolower($filename), -4) == '.csv') {
$filename = substr($filename, 0, -4);
}
$tmpFile = $this
->_getContainer()
->get('kernel')
->getRootDir()
. '/../var/tmp_'.substr(md5(time()),0,5);
if(file_exists($tmpFile)) unlink($tmpFile);
$handle = fopen($tmpFile, 'w');
foreach ($data as $i => $row) {
$row = (array) $row;
if($i == 0) fputcsv($handle, array_keys($row));
fputcsv($handle, $row);
}
fclose($handle);
$Response = new Response(file_get_contents($tmpFile));
unlink($tmpFile);
$filename = preg_replace('[^a-z0-9A-Z_]', '', $filename);
$headers = array_merge([
'Expires' => 'Tue, 01 Jul 1970 06:00:00 GMT',
'Cache-Control' => 'max-age=0, no-cache, must-revalidate, proxy-revalidate',
'Content-Disposition' => 'attachment; filename='.$filename.'.csv',
'Content-Type' => 'text/csv',
'Content-Transfer-Encoding' => 'binary',
], $headers);
foreach ($headers as $key => $val) {
$Response->headers->set($key, $val);
}
return $Response;
}
How about using Sonata's Exporter:
use Exporter\Writer\CsvWriter;
/**
* #param array $orders
*/
public function exportToCsv($orders)
{
$rootdir = $this->get('kernel')->getRootDir();
$filename = $rootdir . '/data/orders.csv';
unlink($filename);
$csvExport = new CsvWriter($filename);
$csvExport->open();
foreach ($orders as $order)
{
$csvExport->write($order);
}
$csvExport->close();
return;
}
It crashes if the file already exists, thus the unlink-command.