HTML Helper syntax issue - html-helper

I have this piece of code in a couple of cshtml pages:
#model bt2.Models.ScheduleWork
#using System.Security.Claims;
#{
bool Admin = User.IsInRole("Admin");
var identity = (ClaimsIdentity)User.Identity;
int Employee_ID = Int32.Parse(identity.FindFirst("DatabaseID").Value);
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
If I understand correctly, I should be able to turn this into a html helper. But I can't find the correct syntax.
I have created a cshtml called bthelper.cshtml and placed it in the App_Code folder
This was my first try:
#helper GetUserInfo() {
// Load user info into sever side variables for subsequent use
// Admin (true if an admin user)
// Employee_Id
#using System.Security.Claims;
#{
bool Admin = (User.IsInRole("Admin"));
var identity = (ClaimsIdentity)User.Identity;
int Employee_ID = Int32.Parse(identity.FindFirst("DatabaseID").Value);
}
}
Then my view cshtml became
#model bt2.Models.ScheduleWork
#bthelper.GetUserInfo()
#using (Html.BeginForm())
{
..........
....
When I run this I get
Unexpected "{" after "#" character. Once inside the body of a code block (#if {}, #{}, etc.) you do not need to use "#{" to switch to code.
With the highlight on the #{ line in the helper
So I tried all the permutations below, all with error messages
#helper GetUserInfo() {
#using System.Security.Claims;
bool Admin = (User.IsInRole("Admin"));
var identity = (ClaimsIdentity)User.Identity;
int Employee_ID = Int32.Parse(identity.FindFirst("DatabaseID").Value);
}
Unexpected "using" keyword after "#" character. Once inside code, you do not need to prefix constructs like "using" with "#".
Error on the #using line
#helper GetUserInfo() {
using System.Security.Claims;
bool Admin = (User.IsInRole("Admin"));
var identity = (ClaimsIdentity)User.Identity;
int Employee_ID = Int32.Parse(identity.FindFirst("DatabaseID").Value);
}
Namespace imports and type aliases cannot be placed within code blocks. They must immediately follow an "#" character in markup. It is recommended that you put them at the top of the page, as in the following example:
#using System.Drawing;
#{
// OK here to use types from System.Drawing in the page
}
Oh..... according to this my original syntax was actually correct
Can someone help me with the correct syntax? Razor syntax still confuses me. Contradictory error messages don't help

Related

How to load/execute a view template from a string in CakePHP

I've developed a CakePHP plugin that allows the site administrator to define custom reports as a list of SQL queries that are executed and the results displayed by a .ctp template.
Now I need to allow the administrator to edit the template, stored in the DB together with the report.
Therefore I need to render a template that is inside a string and not in a .ctp file and I could not find anything in the core that helps.
I considered initially the approach to write the templates in .ctp files and load them from there, but I suspect this solution is rigged with flaws re: the location of the files and related permissions.
A better solution seems to override the View class and add a method to do this.
Can anyone suggest a better approach ?
P.S. Security is not a concern here, since the administrator is basically a developer without access to the code.
In CakePHP 2.0:
The View::render() method imports the template file using
include
The include statement includes and evaluates the specified file.
The evaluated template is immediately executed in whatever scope it was included. To duplicate this functionality, you would need to use
eval()
Caution: The eval() language construct is very dangerous because it
allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
(This warning is speaking to you, specifically)
...if you wish to continue... Here is a basic example of how you might achieve this:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
echo $template;
// Output: Hello ...
eval(' ?>' . $template . '<?php ');
// Output: Hello world...
Which is (almost) exactly the same as:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
file_put_contents('path/to/template.php', $template);
include 'path/to/template.php';
Except people won't yell at you for using eval()
In your CakePHP application:
app/View/EvaluatorView.php
class EvaluatorView extends View
{
public function renderRaw($template, $data = [])
{
if (empty($data)) {
$data = $this->viewVars;
}
extract($data, EXTR_SKIP);
ob_start();
eval(' ?>' . $template . '<?php ');
$output = ob_get_clean();
return $output;
}
}
app/Controller/ReportsController.php
class ReportsController extends AppController
{
public function report()
{
$this->set('name', 'John Galt');
$this->set('template', 'Who is <?php echo $name; ?>?');
$this->viewClass = 'Evaluator';
}
}
app/View/Reports/report.ctp
// Content ...
$this->renderRaw($template);
Alternatively, you may want to check out existing templating engines like: Mustache, Twig, and Smarty.
Hmmm.. Maybe create a variable that will store the generated code and just 'echo' this variable in ctp file.
I had similar problem (cakephp 3)
Controller method:
public function preview($id = null) {
$this->loadModel('Templates');
$tempate = $this
->Templates
->findById($id)
->first();
if(is_null($template)) {
$this->Flash->error(__('Template not found'));
return $this->redirect($this->referer());
}
$html = $template->html_content;
$this->set(compact('html'));
}
And preview.ctp is just:
<?= $html

Self validation of links from HTML-Helper?

How can I prevent links automaticly from beeing displayed in the Template ctp files?
I will give you an example:
User(id = 1) is allowed to see teamcalendars/view/1
User(id = 2) is not allowed to see teamcalendars/view/1.
User1 is member of the team 1 and should see and follow the link. User2 is not member in any teams and neither should see the link to the calender nor follow it. But I would like to place the link in the teams/index file where both users can go to and see all teams, but with different options per team.
If User2 follows the link (or types it into the browser manually), the controller will return a redirect and a error message about missing privileges. User2 will anyhow never get there. But how do I prevent cake from displaying the link for User2 (its missleading)?
Is there a possibility to connect the link to the controller and action and the id of the object where it is leading to, so I don't neet to take care of building and passing variables for each view just to decide which links can be displayed?
Sorry for not providing any code, but I think anyone knows how to send an array from the Controller to the View and how to validate it with if(){echo $this->Html->link()}, which is what I am doing currently.
Thank you for any help or remarks in advance.
One option is to define your own HtmlHelper and override the link function, such that it checks the permissions on the link first and only outputs it if they are allowed access. Something like the following:
namespace App\View\Helper;
use \Cake\View\Helper\HtmlHelper;
// Or, if you're already using a third-party HTML helper, something like
// use BootstrapUI\View\Helper\HtmlHelper as HtmlHelper;
class MyHtmlHelper extends HtmlHelper
{
function link($title, $url = null, array $options = [])
{
if (checkMyPermissions($url)) {
return parent::link($title, $url, $options);
}
}
}
And then in your AppController:
use App\View\Helper\MyHtmlHelper;
public $helpers = [
'Html' => ['className' => 'MyHtmlHelper'],
// ... and all your other helpers
];

Inserting image into visualforce email template (without hard-coding IDs)

The "official" solution for including images in visualforce email templates suggests hard coding IDs in your template to reference an image file stored as a document.
https://help.salesforce.com/HTViewHelpDoc?id=email_template_images.htm&language=en_US
Is there a better way that avoids hard coding instance ID and OID? I tried using the partner URL to grab the instance ID, but I got the following error
Error Error: The reference to entity "oid" must end with the ';' delimiter.
Using:
{!LEFT($Api.Partner_Server_URL_140,FIND(".com/",$Api.Partner_Server_URL_140)+3)/
to replace "https://na2.salesforce.com/"
in
"na2.salesforce.com/servlet/servlet.ImageServer?id=01540000000RVOe&oid=00Dxxxxxxxxx&lastMod=1233217920"
Should I use a static resource instead?
I've arrived here looking for an answer for this question related to hardcoded ID and OID in Visualforce e-mail templates. Well, I found a workaround for that.
First I needed to create a Visualforce Component:
<apex:component access="global" controller="LogomarcaController">
<apex:image url="{!LogoUrl}" />
</apex:component>
In the respective controller class, I've created a SFInstance property to get the correct URL Salesforce Instance, LogoUrl property to concatenate SFInstance and IDs... And Finally I've used Custom Settings (Config_Gerais__c.getInstance().ID_Documento_Logomarca__c) to configurate the ID of Image (in my case, Document Object) on Sandbox or Production:
public class LogomarcaController {
public String LogoUrl {
get {
id orgId = UserInfo.getOrganizationId();
String idDocumentoLogomarca = Config_Gerais__c.getInstance().ID_Documento_Logomarca__c;
return this.SfInstance + '/servlet/servlet.ImageServer?id=' + idDocumentoLogomarca + '&oid=' + orgId ;
}
}
public String SfInstance
{
get{
string SFInstance = URL.getSalesforceBaseUrl().toExternalForm();
list<string> Dividido = SFInstance.split('.visual', 0);//retira o restante a partir de .visual
SFInstance = dividido[0];
dividido = SFInstance.split('://',0);//retira o https://
SFInstance = dividido[1];
if(!SFInstance.contains('sybf')) //managed package prefix, if you need
{
SFInstance = 'sybf.'+ SFInstance;
}
return 'https://'+SFInstance;
}
}
}
And finally, I've added the component in Visualforce template:
<messaging:emailTemplate subject="Novo OfĂ­cio - {!relatedTo.name}" recipientType="User" relatedToType="Oficio__c" >
<messaging:htmlEmailBody >
<c:Logomarca />
</messaging:htmlEmailBody>
<messaging:plainTextEmailBody >
</messaging:plainTextEmailBody>
</messaging:emailTemplate>
PS: Some of my variables, properties and comments are in my native language (portuguese). If you have some problems understanding them, please ask me!
We ran into a similar problem and after trying various solutions, the following worked for us. In our case the image is uploaded as a content asset(https://help.salesforce.com/articleView?id=000320130&type=1&language=en_US&mode=1)
Solution:
<img src="{!LEFT($Api.Partner_Server_URL_260,FIND('/services',$Api.Partner_Server_URL_260))}/file-asset-public/<Image_Name_Here>?oid={!$Organization.Id}&height=50&width=50"/>

Codeigniter urls in multiple languages but handled by the same controller

Let's say I would like to list products on a codeigniter project and support multiple languages, so that someone would select english and get the url example.com/products/5 where 5 is the page number, and someone else would select italian and go get example.com/prodotti/5 . Behind the scenes, I want to have a controller that gets passed a language parameter and a page number parameter to handle these requests. I have a small number of situations like this, and I was thinking about creating two controllers named products and prodotti and then calling a third controller from each one of them by giving it the parameters that it needs.
Is there a better way? Is this achievable with routes?
Here's how I've solved it:
application/config/routes.php
$route['products/(.*)'] = 'products/en/$1';
$route['prodotti/(.*)'] = 'products/it/$1';
application/controllers/products.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Products extends CI_Controller {
public function index($lang, $nr)
{
echo 'lang: ', $lang, ' nr: ',$nr;
}
// https://gist.github.com/1096571
function _remap($method)
{
$param_offset = 2;
if ( ! method_exists($this, $method))
{
$param_offset = 1;
$method = 'index';
}
$params = array_slice($this->uri->rsegment_array(), $param_offset);
call_user_func_array(array($this, $method), $params);
}
}

CakePHP Component not working

Hey guys, I'm working on a cakephp app that manages a list of alpha users. It's a simple form that accepts a name and email and then generates an alpha code after submission, that alpha code is then stored in the record with the name and email under the column "code." I'm using a component calleed PasswordHelper which is located here
Here' my code
class AlphaUsersController extends AppController {
var $name = 'AlphaUsers';
var $components = array('PasswordHelper');
function add() {
if(!empty($this->data)) {
if($this->AlphaUser->save($this->data)){
$this->AlphaUser->set('code', generatePassword(10));
$this->AlphaUser->save();
$this->Session->setFlash('User has been added.');
$this->redirect(array('action' => 'index'));
}
}
}
}
The form data saves just fine when I don't include the alpha code lines, but when I try to generate the password, I get this error.
Fatal error: Call to undefined function generatepassword() in /Users/Warren/Sites/caroverload/app/controllers/alpha_users_controller.php on line 22
What's going on here? I have the PasswordHelper file saved in the appropriate components directory and it's added in the components array for this controller.
I think the way you are calling the PasswordHelper methods should look more like this: $this->PasswordHelper->generatePassword(10).
As you have it now, it is looking for that as a global function, which doesn't exist and throws the error.

Resources