Return HTML code inside PHP function return - php

I am very new to PHP and I was handed over a project that has some existing PHP code.
I was asked to add hyperlink to the email address, so I want to know how to add HTML code in the function return.
public function mail()
{
return (new Mail)
->subject('Welcome')
->message('Send questions to', xxx#email.com);
}
Let's assume that everything in the Mail class works. Both of the subject and message methods return the strings inside the brackets.
Can anyone tell me if this code works? I can't run the program for some reason

Usually we write like this
public function returnHtml {
echo "//and here we write html code"
//for example
echo "<h1> hi<h1>"
}
also you can try something like this
function TestBlockHTML ($replStr) {
return <<<HTML
<html>
<body><h1>{$replStr}</h1>
</body>
</html>
HTML;
}

Related

Can't understand why I'm receiving an error with codecept

I'm writing a small test program where I want to reach login form and to fill it. However, I receive an error.
Here's what I got in my code:
<?php
class loginCest
{
public function frontpageWorks(AcceptanceTester $I)
{
$I->wantTo("Create login test");
$I->amOnPage('my link');
$I->see("join");
$I->fillField('.form-control', 'my_login');
}
}
I would try with a strict locator like:
$I->fillField(['name' => 'userIdentifier'], 'my_login');
because codeceptions might find more than one element (and even a non-input) with the class .form-control

Laravel mail: pass string instead of view

I want to send a confirmation e-mail using laravel.
The laravel Mail::send() function only seems to accept a path to a file on the system.
The problem is that my mailtemplates are stored in the database and not in a file on the system.
How can I pass plain content to the email?
Example:
$content = "Hi,welcome user!";
Mail::send($content,$data,function(){});
update on 7/20/2022: For more current versions of Laravel, the setBody() method in the Mail::send() example below has been replaced with the text() or html() methods.
update: In Laravel 5 you can use raw instead:
Mail::raw('Hi, welcome user!', function ($message) {
$message->to(..)
->subject(..);
});
This is how you do it:
Mail::send([], [], function ($message) {
$message->to(..)
->subject(..)
// here comes what you want
->setBody('Hi, welcome user!'); // assuming text/plain
// or:
->setBody('<h1>Hi, welcome user!</h1>', 'text/html'); // for HTML rich messages
});
For Html emails
Mail::send(array(), array(), function ($message) use ($html) {
$message->to(..)
->subject(..)
->from(..)
->setBody($html, 'text/html');
});
It is not directly related to the question, but for the ones that search for setting the plain text version of your email while keeping the custom HTML version, you can use this example :
Mail::raw([], function($message) {
$message->from('contact#company.com', 'Company name');
$message->to('johndoe#gmail.com');
$message->subject('5% off all our website');
$message->setBody( '<html><h1>5% off its awesome</h1><p>Go get it now !</p></html>', 'text/html' );
$message->addPart("5% off its awesome\n\nGo get it now!", 'text/plain');
});
If you would ask "but why not set first argument as plain text ?", I made a test and it only takes the html part, ignoring the raw part.
If you need to use additional variable, the anonymous function will need you to use use() statement as following :
Mail::raw([], function($message) use($html, $plain, $to, $subject, $formEmail, $formName){
$message->from($fromEmail, $fromName);
$message->to($to);
$message->subject($subject);
$message->setBody($html, 'text/html' ); // dont miss the '<html></html>' or your spam score will increase !
$message->addPart($plain, 'text/plain');
});
Hope it helps you folks.
The Mailer class passes a string to addContent which via various other methods calls views->make(). As a result passing a string of content directly won't work as it'll try and load a view by that name.
What you'll need to do is create a view which simply echos $content
// mail-template.php
<?php echo $content; ?>
And then insert your string into that view at runtime.
$content = "Hi,welcome user!";
$data = [
'content' => $content
];
Mail::send('mail-template', $data, function() { });
I had a similar issue where the HTML and/or plain text of my email were not built by a view and I didn't want to create a dummy view for them (as proposed by #Matthew Odedoyin).
As others have commented, you can use $this->html() to set the HTML content of the message, but what if you want your email to have both HTML and plain text content?
Unfortunately $this->text() only takes a view, but I got around this by using:
$this->text(new HtmlString('Here is the plain text content'));
Which renders the content of the HTMLString instead of the view.
try
public function build()
{
$message = 'Hi,welcome user!'
return $this->html($message)->subject($message);
}
as you know
Only mailables may be queued.
meaning, if you use ShouldQueue interface
1) first, you should always do
php artisan queue:restart
2) second, in your mailable you can use html method (tested in laravel 5.8)
public function build(): self
{
return $this
->html('
<html>
<body>
ForwardEmail
</body>
</html>
')
->subject(config('app.name') . ' ' . 'email forwarded')
->attachData($this->content, 'email.eml', [
'mime' => 'application/eml',
]);
}
If you were using mailables. You can do something like this in the build method :
public function build()
{
return $this->view('email')
->with(['html'=>'This is the message']);
}
And you just go ahead and create the blade view email.blade.php in your resource folder.
Then in the blade you can reference your string using laravel blade syntax
<html>
<body>
{{$html}}
</body>
</html>
or
<html>
<body>
{!!$html!!}
</body>
</html>
If your raw text contains HTML mark up
I hope this works for those who have templates stored in the database and wants to take advantage of the Mailables class in Laravel.
To send raw html, text etc using Laravel Mailables you can
override Mailable->send() in your Mailable and in there, use the method in previous responses:
send([], [], function($message){ $message->setBody() } )
No need to call $this->view() at your build function at all.
NOTE: Below answer is for those who are looking for a flexible approach. i,e (with or without laravel template)
With Template
$payload['message'] = View::make('emails.test-mail',$data)->render();
Without Template
$payload['message'] = "lorem ipsum";
Mail::raw([], function ($mail) use ($payload) {
$mail->from($payload['from_email'])
->to($payload['to'])
->setBody($payload['message'], 'text/html')
->cc($payload['cc'])
->bcc($payload['bcc'])
->subject($payload['subject']);
foreach ($payload['attachments'] as $file){
$mail->attach($file);
}
});
This can be accomplished within a Mailable implementation, with plain text and html content parts:
public function build() {
// Text and html content sections we wish to use in place of view output
$bodyHtml = ...
$bodyText = ...
// Internally, Mailer::renderView($view) interprets $view as the name of a blade template
// unless, instead of string, it is set to an object implementing Htmlable,
// in which case it returns the result $view->toHtml()
$htmlViewAlternative = new class($bodyHtml) implements Htmlable {
protected string $html;
public function __construct($html) {
$this->html = $html;
}
public function toHtml(): string {
return $this->html;
}
};
// We can now set both the html and text content sections without
// involving blade templates. One minor hitch is the Mailable::view($view)
// documents $view as being a string, which is incorrect if you follow
// the convoluted downstream logic.
/** #noinspection PhpParamsInspection */
return $this
->to(...)
->from(...)
->subject(...)
->view([
'html' => $htmlViewAlternative,
'raw' => $bodyText
]);
}
Laravel mailable now has an ->html() function to be used instead of ->view() and works both with o without ->text()
laravel 9 has built in function to send HTML without view. Here is the example:
\Illuminate\Support\Facades\Mail::html($content, function ($message) {
$message->to("email#example.com")
->subject("Test dev 4")
->from("email#example.com");
});
and also if we use accepted answer will return:
Symfony\Component\Mime\Message::setBody(): Argument #1 ($body) must be
of type ?Symfony\Component\Mime\Part\AbstractPart, string given,
called in
/Users/yaskur/Sites/laravel/mail-builder/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php
on line 23
It's happened because laravel use new library to send email. Previously, use Swiftmailer and now use Symfony Mailer. To send HTML email without view you can also use below code:
Mail::raw("", function ($message) use ($content) {
$body = new \Symfony\Component\Mime\Part\TextPart($content);
$message->to("dyas#example.com")
->subject("Test dev")
->from("no-reply#example.com")
->setBody($body);
});

Can't retrieve parameters

I'm playing with OOP in PHP.
I have this code in my index.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Numbers Class</title>
</head>
<body>
<?php
require_once("numbers.php");
$numbers->start("1","2","3");
echo $numbers->list_numbers();
?>
</body>
</html>
And this in my numbers.php
<?php
// Class creation
class numbers
{
private $n1, $n2, $n3;
// Method creation
public function start ($n1,$n2,$n3)
{
$this->number1=$n1;
$this->number2=$n2;
$this->number3=$n3;
}
public function list_numbers()
{
return $this->number1;
return $this->number2;
return $this->number3;
}
}
// Object instance
$numbers=new numbers();
?>
Now, if what I have read so far about oop in PHP, my output should be
1
2
3
But I'm only getting
1
Why???
What I'm doing wrong???
I'm creating a new object called numbers, it has 3 attributes, I created 2 methods, one for storing the numbers and another to call them back.
I load the class and send the numbers, but somehow I'm failing when calling them back. I lost the second and third number, and I just don't understand why...
With return you're getting out of the function, you can use it only once per function so.
I guess what you want is the echo function
public function list_numbers()
{
echo $this->number1;
echo $this->number2;
echo $this->number3;
}
In your list_numbers() method, you are returning the first value. From http://php.net/manual/en/function.return.php
If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call. return will also end the execution of an eval() statement or script file.
If you replaced return with echo in your list_numbers() method, you would get the output you are expecting.
Also, you didn't "lose" the numbers. You can verify this by doing a var_dump($this).
Antoine's and Ben's explanations are good, but the suggested repair might also be
public function list_numbers()
{
return array($this->number1, $this->number2, $this->number3);
}
In this case, you get array from the function by
$nums = $numbers->list_numbers();
You can now print this array or do anything else you might want with it, the same way you would do it with any other array.
Change to this...
public function list_numbers()
{
return array($this->number1, $this->number2,return $this->number3);
}
Then in your php file....
<?php
require_once("numbers.php");
$numbers->start("1","2","3");
$nums = $numbers->list_numbers();
//use it in a loop or just print_r it or whatever....
foreach($nums as $val){
echo "Number is : ".$val;
}

php function in array broken

I am trying to setup an array that pulls the filename and function name to run, but it not fully working.
The code is
$actionArray = array(
'register' => array('Register.php', 'Register'),
);
if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) {
echo '<br><br>index<br><br>';
echo 'test';
exit;
}
require_once($actionArray[$_REQUEST['action']][0]);
return $actionArray[$_REQUEST['action']][1];
Register.php has
function Register()
{
echo 'register';
}
echo '<br>sdfdfsd<br>';
But it does not echo register and just sdfdfsd.
If I change the first lot of code from
return $actionArray[$_REQUEST['action']][1];
to
return Register();
It works, any ideas?
Thanks
Change the last line to:
return call_user_func($actionArray[$_REQUEST['action']][1]);
This uses the call_user_func function for more readable code and better portability. The following also should work (Only tested on PHP 5.4+)
return $actionArray[$_REQUEST['action']][1]();
It's almost the same as your code, but I'm actually invoking the function instead of returning the value of the array. Without the function invocation syntax () you're just asking PHP get to get the value of the variable (in this case, an array) and return it.
You'll find something usefull here:
How to call PHP function from string stored in a Variable
Call a function name stored in a string is what you want...

DOMDocument::saveHTML($domnode) in PHP 5.2?

I have several functions in a class that return saveHTML(). After I echo more than one function in the class saveHTML(), it repeats some of the HTML. I initially solved this by doing saveHTML($node) but that doesn't seem to be an option now.
I didn't know saveHTML($domnode) was only available in PHP 5.3.6 and I have no control over the server I uploaded the files to so now I have to make it compatible with PHP 5.2.
For simplicity's sake it and only to show my problem it looks similar to this:
<?php
class HTML
{
private $dom;
function __construct($dom)
{
$this->dom = $dom;
}
public function create_paragraph()
{
$p = $this->dom->createElement('p','Text 1.');
$this->dom->appendChild($p);
return $this->dom->saveHTML();
}
public function create_paragraph2()
{
$p = $this->dom->createElement('p','Text 2.');
$this->dom->appendChild($p);
return $this->dom->saveHTML();
}
}
$dom = new DOMDocument;
$html = new HTML($dom);
?>
<html>
<body>
<?php
echo $html->create_paragraph();
echo $html->create_paragraph2();
?>
</body>
</html>
Outputs:
<html>
<body>
<p>Text 1.</p>
<p>Text 1.</p><p>Text 2.</p>
</body>
I have an idea why it's happening but I have no idea how to not make it repeat without saveHTML($domnode). How can I make it work properly with PHP 5.2?
Here's an example of what I want to be able to do:
http://codepad.viper-7.com/o61DdJ
What I do, is just save the node as XML. There are a few differences in the syntax, but it's good enough for most uses:
return $dom->saveXml($node);
You have return $this->dom->saveHTML(); twice in your class ( as far as I know you don't have to return it inside the class anywhere unless it is a private function.
If you take return $this->dom->saveHTML(); out of createparagraph() it will echo without returning. It's a DOM thing as far as I know but am new to this like you.

Categories