Dynamically get MessageBag from ViewErrorBag? - php

In my app, I have a generic place for errors in the view that I display simply using:
show_messages($errors->getMessages());
In the show_messages function I parse out the errors in the way I would like them displayed. However I started using some grouping in my forms like register[email]. When I display the errors I use ->withErrors(Input::get('register'), 'register').
But now I can't dynamically get the messages becasue $errors->getMessages() goes to default message bag by default (which in this case is empty).
I can get the errors using $errors->register->getMessages(), but that's assuming I know it will be register. Looking at the ViewErrorBag class I don't see any methods to provide the bag. Is there anyway to do this without altering the current class to get all the bags dynamically or all the messages in each bag dynamically?

I don't know if this works in Laravel 4, but in Laravel 5 I use $errors->all().

You could simply iterate over all of the object properties.
foreach ($errors as $errorBag) {
show_messages($errorBag->getMessages());
}
While theoretically you would need to check for the property type to know if it's a MessageBag, MessageBag doesn't have any other public properties.

Related

Laravel 5.3 pass multiple MessageBag instances to $errors variable

I have two modal fields on a page with forms and need to determine which of the model fields is has an error.
So my question is:
How can I pass multiple MessageBag's to $errors to be able check errors using $errors->errorType->get('message')?
I found a solution, it is called "Named Error Bags":
First need to manually create validator: https://laravel.com/docs/5.3/validation#manually-creating-validators
and then create named bag in response;

How to check the whole chain of relational chain without check each method separately?

I often get an FatalErrorException that says Call to a member function method() on null. This happens mostly when I use (in blade) long chained sentences where one among them (models) is null. For example:
$file->owners()->first()->categories()->first()->title
so when for example here categories returns null I get this exception. I have to check each method one by one. I can't check them at a time like:
!empty($file->owners()->first()->categories()->first()->title)
!is_null($file->owners()->first()->categories()->first()->title)
isset($file->owners()->first()->categories()->first()->title)
count($file->owners()->first()->categories()->first()->title)
I still get the exception by using these, because (I guess) before getting the final parameter (here 'title') the process goes trough all methods and before it can't get to the final one the exception comes. Actually in controllers this could be guidable to make all these checks but in blade this does not come so relevant to me. Besides, this is a loop. So I am looking how I could do this check at once.
Well if you get null from the first first() call you cannot continue the method chaining. You can always use try ... catch:
try {
$file->owners()->first()->categories()->first()->title
} catch (\Exception $e) {
// do on fail
}
I'd recommend using View Presenter in your project. It really helps you to keep your code clean by moving all extra logic from your views and put it in a dedicated presenter class.
Watch this laracasts video to learn more.

Call to undefined function Laravel

I have problem when I'm checking if collection is empty or not, Laravel gives me error
"Call to undefined method
Illuminate\Database\Query\Builder::isEmpty()".
Tho it work in other Controller, but when controller is in Sub folder is suddenly stops working.
Here is my code:
$group = UserGroup::where('id', $request->group_id)->first();
if($group->isEmpty()){ // I get error from here
return redirect()->back();
}
One of the most popular way of debugging in PHP still remains the same – showing variables in the browser, with hope to find what the error is. Laravel has a specific short helper function for showing variables – dd() – stands for “Dump and Die”, but it’s not always convenient. What are other options?
Note the below mentioned methods are to find where our class fails and what are all the conditions that are available after our query executes. What is our expected result before printing it. This methods are the best methods to find out the error as required by is.
First, what is the problem with dd()? Well, let’s say we want to get all rows from DB table and dump them:
$methods = PaymentMethod::all();
dd($methods);
We would see like this:
But you get the point – to see the actual values, we need to click three additional times, and we don’t see the full result without those actions. At first I thought – maybe dd() function has some parameters for it? Unfortunately not. So let’s look at other options:
var_dump() and die():
Good old PHP way of showing the data of any type:
$methods = PaymentMethod::all();
var_dump($methods);
die();
What we see now:
But there’s even more readable way.
Another PHP built-in function print_r() has a perfect description for us: “Prints human-readable information about a variable”
$methods = PaymentMethod::all();
print_r($methods);
die();
And then go to View Source of the browser… We get this:
Now we can read the contents easily and try to investigate the error.
Moreover, print_r() function has another optional parameter with true/false values – you can not only echo the variable, but return it as string into another variable. Then you can combine several variables into one and maybe log it somewhere, for example.
So, in cases like this, dd() is not that convenient – PHP native functions to the rescue. But if you want the script to literally “dump one simple variable and die” – then dd($var) is probably the fastest to type.

Adding a field specific error from the controller in symfony2

I have some complex validation going on with my symfony form, and I need to be able to assign an error to a specific field from my controller. Right now, I have global errors working like this:
$error = new formerror("There is an error with the form");
$form->addError($error);
But that creates a global error, not one bound to a specific field.
Is there a way to throw an error on a specific field from my controller?
Thanks to some help over IRC (thanks #fkrauthan!) I came up with an answer.
Every field in SF2 is actually an instance of form. What you need to do is access the form object of the field, and add then error onto it. Thankfully, symfony provides a method to get an embedded form/field.
Heres my code:
$error = new FormError("There is an error with the field");
$form->get('field')->addError($error);
As some people have pointed out, you will need to include the FormError class at the top of your file:
use Symfony\Component\Form\FormError;

Can I pass data to the Codeigniter output class without displaying it?

I'm working on a way for users to be able to generate PDF copies of invoices and other tabular data. To do this, I've wrapped dompdf into a library that I can use with CI and created a method that will generate a PDF based on the return value of CI's output->get_output(). The wrapper is similar to this one on Github.
The problem is, I can't figure out a way to get the view (and HTML/CSS needed for the PDF) into CI's output class other than load->view(), which is going to write to the browser.
My only other choice would be to use curl to request the page, but that seems so silly to do since I can get it right from the output buffer. I just don't want the HTML sent to the browser, since I set headers telling the browser to expect a PDF.
To be clear, this is what I want to accomplish (in the order that I want to accomplish it):
Do everything I'd normally do to prepare the view for display
Load the view into the CI output class, but not display it
Pass the return value of output->get_output() to my dompdf library
Set the appropriate headers
Execute my dompdf method that will send the PDF to the browser
I don't see any way of doing step 2 based on the output class documentation.
Is it possible to get a view into the output class without displaying it? If so, how? I'm using CI 2.0.3.
Edit
The very helpful Anthony Sterling pointed out that I can just get what I want from the loader class by setting the third argument telling it to return a string rather than render the view to TRUE. E.g.:
$lotsaHtml = $this->load->view('fooview', $somearray, TRUE);
And that would be better in my particular instance since I don't need to load partials. However, this is still a valid and (I think) interesting question, it would also be handy to know if I could get the same from the OB, perhaps if I did have a bunch of partials. Those could be concatenated, but yuck.
It seems like I should be able to get the output class to not render anything (else, why does get_output() exist?) so I can do something else with everything it knows about. I just can't find a way to make that happen.
Edit 2
Some pseudo (but not far from reality) code illustrating what I hope to do, by showing what I did and then explaining what I actually wanted to do.
Let's say I have a public method genpdf($id) in a controller named invoice using a model named inv:
public function genpdf($invoiceId) {
$this->load->library('dompdflib');
$this->pagedata['invoice_data'] = $this->inv->getInvoice($invoiceId);
$html = $this->load->view('pdfgen', $this->pagedata, TRUE);
$this->dompdflib->sendPdf($html);
}
That is almost identical to code that I have that works right now. There, I ask the loader to parse and give me the results of the pdfgen view as a string, which I pass to the function in my dompdf wrapper that sets headers and sends the PDF to the browser.
It just seemed like this would be easy to do by just getting the output buffer itself (after setting headers correctly / etc).
Or do I just have to call the output class append_output() in succession with every partial I load?
Multiple methods loading a plethora of models need to work together to generate these (they're going in as an afterthought), so I was hoping to just collect it all and retrieve it directly from the output class. It could be that I just have to talk gradually to output->append_output() to make that happen.
...so - do I understand correctly - you want to get the whole final output (not just the view) as a string AND not display it to the user? Why dont you just overload the controllers _output() function?
class Your_controller extends CI_Controller
{
function stuff()
{
// do whatever - prep $data etc
$this->load->view('your_view', $data);
}
function _output($output)
{
// send $output to your library - get results blah blah
$result_pdf_file = $this->your_pdf_library_generator($output);
// Show something else to the user
echo "hi - I'm not what you expected - but here is your PDF";
echo $result_pdf_file; // or something like that
}
}
This means you can send ANYTHING you like to the output class - but nothing is displayed except what you want.
There are ways to improve this idea (i.e. hooks, variables to turn output on/off etc) - but the simplest would be to have this controller specifically for your pdf_generation command.
I don't see any way of doing step 2 based on the output class documentation. Is it possible to get a view into the output class without displaying it? If so, how? I'm using CI 2.0.3.
The controller _output() documentation is actually in the CI controller documentation, which is why it eluded you.

Categories