Allow $title argument with HTML code - hyperlink

I work with Laravel 4.
I want to use the HTML::linkAction to provide a link embedded in an image.
The method's prototype is :
linkRoute( string $name, string $title = null, array $parameters = array(), array $attributes = array() )
Then I use the image method to get my <img></img> code :
HTML::linkAction('contact#index', HTML::image('images/contact.png', 'contact'));
It works almost fine. The problem is that the <img></img> code is formatted like htmlspecialchars() do.
Is there a way to allow HTML code in parameters, or to deactivate the htmlspecialchars fonctionality ? Or maybe it's a bad practice ?
Thanks,
Raphaƫl N.

You cannot pass HTML to linkAction(), because it internally calls:
$this->entities()
Here is the code for link(), wich is used by linkAction():
public function link($url, $title = null, $attributes = array(), $secure = null)
{
$url = $this->url->to($url, array(), $secure);
if (is_null($title) or $title === false) $title = $url;
return '<a href="'.$url.'"'.$this->attributes($attributes).'>'.$this->entities($title).'</a>';
}
And there is no options to do it differently.
So if you need to pass an image, you'll have to write HTML for that particular link.

Related

Kendo RadioGroupFor setting HtmlAttributes base on boolean condition

I am trying to use this object item.isRequired to set the HtmlAttributes as required but its not working. It work fine when I use the string value in the HtmlAttributes but not when I use the htmlAttributesData string.
var htmlAttributesData = item.isRequired ? "new { required = 'required', data_val_required = 'Question is Required' }" : "";
#(Html.Kendo().RadioGroupFor(m => m.MeetingPollingQuestions)
.Name(string.Format("PollingResponses[{0}].Value", idx))
.HtmlAttributes(htmlAttributesData)
.Items(i =>
{
foreach (var option in #item.RadioButtonList)
i.Add().Label(option.Label).Value(option.Value);
}
)
.Value("Value")
);
The Html.Kendo() code wrapped in #() is processed on the server to generate javascript before the page is sent to the browser. When the server does this, htmlAttributesData does not exist because that is javascript code as far as I can tell. The server does not execute any javascript logic, it simply sends it to the browser.
Two options:
Don't use the Html.Kendo server wrapper and instead use the query plugin syntax to declare the radio group with javascript. That will be processed on the browser where you can then use htmlAttributesData to set it up because it will exist at that point.
Declare htmlAttributesData using server code. Maybe something like:
.HtmlAttributes(#item.isRequired ? new { required = 'required', data_val_required = 'Question is Required' } : null)

laravel 5.1 trouble with queueing email sending

i'm trying to queue an email sending invoice emails in laravel 5.1, i pass in a variable called invoice, when i dd($invoice->dateString()) in the Job class it's return the correct value but when i pass it in to the view the $invoice variable return empty array (so i get an error about trying to get property from non-object...).
the second problem i have is when i try to add attachment to the job it returns an error : "Serialization of closure failed: Serialization of 'SplFileInfo' is not allowed".
the job class looks like that:
namespace LM2\Jobs;
use Guzzle\Service\Client;
use LM2\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use LM2\Models\User as User;
use LM2\Models\Client as LMClient;
class SendInvoiceEmail extends Job implements SelfHandling, ShouldQueue
{
protected $user;
protected $invoice;
protected $attachment;
protected $update;
public function __construct(User $user, LMClient $client, $invoice,$update)
{
$this->user = $user;
$this->client = $client;
$this->invoice = $invoice;
$this->update = $update;
}
public function handle()
{
$attachment = $this->client->invoiceFile($this->invoice->id,['vendor' => 'Test','product' => 'Your Product']);
$invoice = $this->invoice;
$data = [
'invoice' => $this->invoice,
'update'=> $this->update,
];
$user = $this->user;
\Mail::queue('emails.invoices', $data , function($m) use ($user,$invoice,$attachment){
$m->to($user->email)->subject('New payment received')->attach($attachment);
});
}
}
and my controller function looks like that:
public function sendEmailInvoice($update = false){
$client = \Auth::client();
$user = \Auth::user();
$invoices = $client->invoices();
$this->dispatch(new SendInvoiceEmail($user,$client,$invoices[0],$update));
$activity = $data['update'] ? 'updated': 'added';
return ['success', $activity];
}
can someone please tell me what am i doing wrong?
thanks a lot you all :)
Just a guess... but when using Mail::queue() the $data get's converted/cast to an array/you lose your objects inside of the view - hence why you're receiving errors when trying to call methods(), because they don't exist.
Rather than passing invoice + update objects, get what you need from them in the handle method and construct the $data array.
$data = [
'invoice_foo' => $invoice->getFoo(),
'invoice_bar' => $invoice->getBar(),
];
*** Apologies if this doesn't help at all!
so i found the answer thanks to #Michael, i have changed my handle so it's look like this now:
public function handle(Mailer $mailer)
{
$client = $this->client;
$invoice = $this->invoice;
$data = [
'date' => $invoice->dateString(),
'amount' => $invoice->dollars(),
'update'=> $this->update,
];
$user = $this->user;
return $mailer->queue('emails.invoices', $data , function($m) use ($user,$client,$invoice){
$attachment = $client->invoiceFile($invoice->id,['vendor' => 'Infogamy','product' => 'Your Product']);
$m->to($user->email)->subject('New payment received')->attach($attachment);
});
}
The attachment should be processed inside the mailer callback function, and the function called from the $invoice variable (object) should be called inside the handle function and not in the blade view template.

Get local value in layout or view in Zend Framework 2

How can we get local value (i.e: 'en' or 'en_US', 'de' etc) in layout.phtml or views in Zend Framework 2?
My local setting are exactly same as explained here
<?php
namespace FileManager;
use Zend\Mvc\ModuleRouteListener;
class Module
{
public function onBootstrap($e)
{
$translator = $e->getApplication()->getServiceManager()->get('translator');
$translator
->setLocale(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']))
->setFallbackLocale('en_US');
}
//...
}
I want to get local value something like this:
$locale = $this->translate()->getLocale(); // <-- It's not working anyway
I need to use '$locale' it while calling google map api url to get matched locale/language. I'm calling it throughtout the application in layout.phtml
$this->headScript()->appendFile('http://maps.googleapis.com/maps/api/js?language=' . $locale);
So I want to make language option dynamic while calling api.
PS: I don't have any query string parameter such as 'language', It's a google api thing which I need to set in script url (if you don't know) Please don't get confused.
Not answered here
Depends on where you want to get the Locale value from. In any case, you can do it in your controller, e.g.:
$locale = $this->request->getQuery('language');
$this->layout()->locale = $locale;
or
return new ViewModel(array('locale' => $locale));
Edit if you just want to get the locale from the translator, you can try this in view script:
$this->plugin('translate')->getTranslator()->getLocale();
My version is like that
<?php
namespace FileManager;
use Zend\Mvc\ModuleRouteListener;
use Zend\Session\Container;
class Module
{
public function onBootstrap($e)
{
$application = $e->getTarget();
$serviceManager = $application->getServiceManager();
$eventManager = $application->getEventManager();
$events = $eventManager->getSharedManager();
// session container
$sessionContainer = new Container('locale');
// test if the language in session exists
if(!$sessionContainer->offsetExists('mylocale')){
// doesn't so the browser lan
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
$sessionContainer->offsetSet('mylocale', Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']));
}else{
$sessionContainer->offsetSet('mylocale', 'en_US');
}
}
// translation
$translator = $serviceManager->get('translator');
$translator ->setLocale($sessionContainer->mylocale)
->setFallbackLocale('en_US');
$mylocale = $sessionContainer->mylocale;
$events->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) use ($mylocale) {
$controller = $e->getTarget();
$controller->layout()->mylocale = $mylocale;
}, 100);
}
//...
}
in your layout
$this->headScript()->appendFile('http://maps.googleapis.com/maps/api/js?language=' . $this->mylocale);

Multiple view strategy in zend 2 [duplicate]

So far, I have figured out how to return a typical JSON response in Zend Framework 2. First, I added the ViewJsonStrategy to the strategies section of the view_manager configuration. Then, instead of returning a ViewModel instance from the controller action, I return a JsonModel instance with all my variables set.
Now that I've figured that piece out, I need to understand how to render a view and return it within that JSON response. In ZF1, I was able to use $this->view->render($scriptName), which returned the HTML as a string. In ZF2, the Zend\View\View::render(...) method returns void.
So... how can I render an HTML view script and return it in a JSON response in one request?
This is what I have right now:
if ($this->getRequest()->isXmlHttpRequest()) {
$jsonModel = new JsonModel(...);
/* #todo Render HTML script into `$html` variable, and add to `JsonModel` */
return $jsonModel;
} else {
return new ViewModel(...);
}
OK, i think i finally understood what you're doing. I've found a solution that i think matches your criteria. Though i am sure that there is room for improvement, as there's some nasty handwork to be done...
public function indexAction()
{
if (!$this->getRequest()->isXmlHttpRequest()) {
return array();
}
$htmlViewPart = new ViewModel();
$htmlViewPart->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array(
'key' => 'value'
));
$htmlOutput = $this->getServiceLocator()
->get('viewrenderer')
->render($htmlViewPart);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
}
As you can see, the templateMap i create is ... nasty ... it's annoying and i'm sure it can be improved by quite a bit. It's a working solution but just not a clean one. Maybe somehow one would be able to grab the, probably already instantiated, default PhpRenderer from the ServiceLocator with it's template- and path-mapping and then it should be cleaner.
Thanks to the comment ot #DrBeza the work needed to be done could be reduced by a fair amount. Now, as I'd initially wanted, we will grab the viewrenderer with all the template mapping intact and simply render the ViewModel directly. The only important factor is that you need to specify the fully qualified template to render (e.g.: "$module/$controller/$action")
I hope this will get you started though ;)
PS: Response looks like this:
Object:
html: "<h1>Hello World</h1>"
jsonArray: Array[6]
jsonVar1: "jsonVal2"
You can use more easy way to render view for your JSON response.
public function indexAction() {
$partial = $this->getServiceLocator()->get('viewhelpermanager')->get('partial');
$data = array(
'html' => $partial('MyModule/MyPartView.phtml', array("key" => "value")),
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6));
$isAjax = $this->getRequest()->isXmlHttpRequest());
return isAjax?new JsonModel($data):new ViewModel($data);
}
Please note before use JsonModel class you need to config View Manager in module.config.php file of your module.
'view_manager' => array(
.................
'strategies' => array(
'ViewJsonStrategy',
),
.................
),
it is work for me and hope it help you.
In ZF 3 you can achieve the same result with this code
MyControllerFactory.php
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$renderer = $container->get('ViewRenderer');
return new MyController(
$renderer
);
}
MyController.php
private $renderer;
public function __construct($renderer) {
$this->renderer = $renderer;
}
public function indexAction() {
$htmlViewPart = new ViewModel();
$htmlViewPart
->setTerminal(true)
->setTemplate('module/controller/action')
->setVariables(array('key' => 'value'));
$htmlOutput = $this->renderer->render($htmlViewPart);
$json = \Zend\Json\Json::encode(
array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1, 2, 3, 4, 5, 6)
)
);
$response = $this->getResponse();
$response->setContent($json);
$response->getHeaders()->addHeaders(array(
'Content-Type' => 'application/json',
));
return $this->response;
}
As usual framework developer mess thing about AJAX following the rule why simple if might be complex Here is simple solution
in controller script
public function checkloginAction()
{
// some hosts need to this some not
//header ("Content-type: application/json"); // this work
// prepare json aray ....
$arr = $array("some" => .....);
echo json_encode($arr); // this works
exit;
}
This works in ZF1 and ZF2 as well
No need of view scrpt at all
If you use advise of ZF2 creator
use Zend\View\Model\JsonModel;
....
$result = new JsonModel($arr);
return $result;
AJAX got null as response at least in zf 2.0.0

How bind POST data to object can save to Doctrine

How bind POST data to object can save or edit to Doctrine.
I use Doctrine with annotation entities. I don't figure out as bind array data to entities .
I read about Symfony's components as standalone, too.
Example :
$_POST # form data , array
# this is how doctrine save object
$product = new Product();
$product->setName('product1');
$entityManager->persist($product);
$entityManager->flush();
I want $product = $helper->convert($_POST, ...) # return product object
then i can persist $product to $entityManager.
This will help you how to handle forms:
http://symfony.com/doc/current/book/forms.html
To put data on an Entitiy user the setters.
$entity->setName('Mitchel');
If you want to put a post on a entity you have to create a function like this:
public function setAttributes( array $values )
{
foreach( $values as $attribute => $value ) {
$dateEng = "/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/";
$dateNl = "/^([0-9]{2})-([0-9]{2})-([0-9]{4})$/";
if( preg_match ($dateEng, $value) OR preg_match ($dateNl, $value) ){
$value = date_create( $value );
}
if(is_string( $value )){
if(preg_match( '/^\d+$/', $value )){
$value = (int) $value;
}
}
$this->{'set' . ucfirst( $attribute )}( $value );
}
return $this;
}
This works for me =)
And if I find a case who doesn't works I just add some code.
If you decide to go this way, you should use ClassMetadata class to determine field names first or you will get "PHP Fatal error: Call to undefined method ..." when user post extra data.
Something like this:
<?php
function setAttributes($values) {
$cm = new ClassMetadata(__CLASS__);
foreach ($cm->getFieldNames() as $field) {
if (array_key_exists($values, $field))
$this->{'set' . ucfirst( $attribute )}( $value );
// ...
But I would strongly recommend you to learn Form component. It took me just one day to start and about a week to make complicate forms.

Resources