I'm writing a module in Drupal-7 that dynamically sends a one-time login link to guests. Everything fires fine until I add the link to the $message array, when it chokes. If I do a dpm($message) the link appears in the $message['body'] array, as I would expect. If I comment out the line with the url() function, everything works as it should. Why is php/Drupal choking on this silly little link?
/*
* Implement hook_mail().
*/
function rsvp_mail($key, &$message, $params) {
switch($key) {
case "send invite" :
$timestamp = REQUEST_TIME;
$account = $params['account'];
$message['subject'] = "And invitation for $account->name";
$message['body'][] = 'Some body text.';
$message['body'][] = 'Some more text!';
//here's the line that's breaking my brain:
$message['body'][] = url( 'http://wedding.juicywatermelon.com/rsvp/' . $account->uid . "/" . $timestamp . "/" . md5($account->pass . $timestamp) . "/" . 'user/' . $account->uid . '/edit/Wedding');
break;
}
}
ps - I had the code to generate the link in a seperate function call and moved it to the hook implementation for brevity. This, however had no effect on the behaviour.
and the code that generates the email:
function rsvp_mail_send($account) {
$module = 'rsvp';
$from = "email#gmail.com";
$key = "send invite";
$params['account'] = $account;
$to = $account->mail;
$language = language_default();
$send = TRUE;
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
}
You need to add an extra argument to the url() function which is called options, it's an array and in this array use the key 'absolute' and set it to TRUE to indicate that the URI that you pass as a first argument is an absolute URL.
See the documentation page for more information:
http://api.drupal.org/api/drupal/includes--common.inc/function/url/7
Related
How do I create an anonymous function dynamically when I have function body in a string.
For e.g.
$user = "John Doe";
$body = "echo 'Hello' . $user;";
$myFunct = function($user) {$body}; // How do I have function body here from string.
$myFunct($user);
Any help would be much appreciated.
P.S.
I'm looking for a replacement for create_function() functionality which was there in prior versions of PHP. Just like in create_function() where we could pass the function body as a string, I would like to define anonymous function's body off the string variable.
If you have explored all other options and are absolutely sure the only way to accomplish your goals is to define custom functions at runtime using code that's in a string, you have two alternatives to using create_function.
The quick solution is to just use eval:
function create_custom_function($arguments, $body) {
return eval("return function($arguments) { $body };");
}
$myFunct = create_custom_function('$user', 'echo "Hello " . $user;');
$myFunct('John Doe');
// Hello John Doe
However, eval() can be disabled. If you need this sort of functionality even on servers where eval is not available, you can use the poor man's eval: write the function to a temporary file and then include it:
function create_custom_function($arguments, $body) {
$tmp_file = tempnam(sys_get_temp_dir(), "ccf");
file_put_contents($tmp_file, "<?php return function($arguments) { $body };");
$function = include($tmp_file);
unlink($tmp_file);
return $function;
}
$myFunct = create_custom_function('$user', 'echo "Hello " . $user;');
$myFunct('John Doe');
// Hello John Doe
In all honesty though, I strongly recommend against these approaches and suggest you find some other way to accomplish your goal. If you're building a custom code obfuscator, you're probably better off creating a php extension where the code is de-obfuscated prior to execution, similar to how ionCube Loader and Zend Guard Loader work.
You can use the callable type hint. Here is an example
function callThatAnonFunction(callable $callback) {
return $callback();
}
It can take an anonymous function with any arg params:
$user = "person";
$location = "world";
callThatAnonFunction(function() use ($user, $location) {
echo "Hello " . $user . " in " . $location;
});
You can try this:
$user = "John Doe";
$body = "echo 'Hello' . $user;";
$myFunct = function($user) {
return $body;
};
echo $myFunct($user);
Well this is ugly and you shouldn't really do this, but you said in a comment that you're doing this for a code obfuscator so here are my 2 cents:
$args = '$user, $number';
$body = 'echo "#$number: Hello $user.\n";';
function _create_function_without_eval($args, $body) {
$func_name = sprintf('temp_func_%s', md5($body));
$code = sprintf("<?php if (!function_exists('%s')) {function %s(%s){%s}}", $func_name, $func_name, $args, $body);
$func_file = tempnam('/tmp', $func_name);
$handle = fopen($func_file, "w+");
fwrite($handle, $code);
fclose($handle);
include $func_file;
unlink($func_file);
return function(...$user_args) use ($func_name) {
return call_user_func_array($func_name, $user_args);
};
}
function _create_function_with_eval($args, $body) {
$func_name = sprintf('temp_func_%s', md5($body));
$code = sprintf("if (!function_exists('%s')) {function %s(%s){%s}}", $func_name, $func_name, $args, $body);
eval($code);
return function(...$user_args) use ($func_name) {
return call_user_func_array($func_name, $user_args);
};
}
$fn_deprecated = create_function($args, $body);
$fn_with_eval = _create_function_with_eval($args, $body);
$fn_without_eval = _create_function_without_eval($args, $body);
echo $fn_deprecated('Old Bob', '1');
echo $fn_without_eval('Bob without eval', 2);
echo $fn_with_eval('Bob with eval', 3);
See it live here: https://3v4l.org/urQ4k
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.
so Eval is the worst replacement, create_function is depreicated because of using eval.
use anonymous functions for adiinviter pro.
$b = function () use ($d,$f1,$c,$ps){
return gzinflate( base64_decode(str_rot13($ps) ) );
};
PHP developers love you hahaha look here
$user = "John Doe";
$body = 'echo "Hello " . $a;';
$f = create_function('$a', $body);
$f($user);
//out : Hello John Doe
Documentation PHP official : create_function(string $args,string $code)
I am working on a Learning Management System build upon Moodle. I want to add an email header and footer for each email.
I did some change in Moodle for adding an image in ./lib/moodlelib.php as follows:
function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '', $attachment = '', $attachname = '',
$usetrueaddress = true, $replyto = '', $replytoname = '', $wordwrapwidth = 79) {
global $CFG, $PAGE, $SITE;
// Append image at top
if($messagehtml){
$tmp = $messagehtml;
// Added image here
$messagehtml = '<img src="'.$CFG->wwwroot.'/images/logo.png" alt="LMS" /><br/>';
// $messagehtml = $image;
$messagehtml .= $tmp;
}
if($messagetext){
$tmp = $messagetext;
// Added image here
$messagetext = '<img src="'.$CFG->wwwroot.'/images/logo.png" alt="LMS" /><br/>';
// $messagehtml = $image;
$messagetext .= $tmp;
}
....................
but I want the header and footer as fixed templates. Please help me.
You could create a message header in a language file (in English either directly under /lang/en or in a plugin) and then add the following string in the language file:
$string ['message_header'] = '<p> write here whatever your style and HTML structure you want in your header</p>
adding your image as well <img src="'.$CFG->wwwroot.'/images/logo.png" alt="LMS" />';
Then you could write a string for your footer as well:
$string ['message_footer'] = 'Your HTML footer here';
And finally you could insert your strings in the message:
$message = 'here your body';
// insert message header - if your language string is in /lang/moodle.php:
$message = get_string ( 'message_header') . $message;
// insert message footer - if your language string is in your /local/myplugin:
$message .= get_string ( 'message_footer', 'local_my_plugin' );
This way your header and footer may be customized at will if you change them directly in the language file (or, in the DB. See here).
a little bit too late, but i hope it helps others:
https://docs.moodle.org/dev/Themed_emails just look for e-mail templates in /var/www/html/moodle/lib/templates. The template with a name email_html.mustache should be the right one.
I am using Laravel to create a web bot that collects data from other websites and stores it in my MySQL database. When I want to save body I use dd($this->render($post)); and it is good. Yet, when I use $post->save() for saving my post in db, it not saving the body of my post completely and some of text is missing.
My body is at least 10000 characters and I always have this problem.
I checked text and longtext for body column type and is not there any difference...
Where is problem?
edit :
this is my index method :
public function getIndex()
{
$temp = App\Temp::where('status' , 0)->orderBy('id' , 'desc')->first();
$temp->status = 1;
$temp->save();
$post = new App\Post;
$post->title = $temp->title;
$post->link = $temp->link;
$post->desc = $temp->desc;
$post->cat_id = $temp->cat_id;
$post->url_id = $temp->url_id;
$post->body = $this->render($post);
$post->save();
echo "+";
}
When I am using dd($this->render($post)); before save, it shows full text without any problem... but after save when I fetch the body, some characters is missing from the end of post...
and this is render() method...
public function render($post)
{
echo "Start : ";
$this->ftp->createFolder('/'.$post->url_id.'/'.$post->id."/");
echo "Dir - ";
$mixed_body = $this->desc($post->title);
echo "Mix - ";
$body ="";
$body = $body . '<h3><a href='.$this->postUrl.'>'.$this->postTitle.'</a></h3>';
echo "Title - ";
while(strlen($mixed_body) > 100)
{
$body = $body . $this->randImage($post);
$body = $body . $this->randTitle();
//insert a random paragraph
$number = rand(100 , strlen($mixed_body));//temporary
$paragraph = substr($mixed_body , 0 , $number);
$mixed_body = substr($mixed_body , $number , strlen($mixed_body)-$number);
$body = $body . '<p>' . $paragraph . '</p>';
echo "P|";
}
echo "\nDone : ".strlen($body);
return $body;
}
others methods in render() are appending some text to $body and those are not important.
and my model :
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
public function tags()
{
return $this->hasMany('App\Tag');
}
}
I find my problem reason...
sometimes I have a character like � in my body that laravel not saves the characters after it...
I find to use this line to delete � character...
$post->body = mb_convert_encoding($this->render($post), 'UTF-8', 'UTF-8');
thanks from all to help me, I have a very bad headache and want to rest...
thanks from all again, good night/morning/afternoon (according to your time-zones) :)
First lemme tell you what i am trying to achieve here . Suppose there is a url like this http://www.example.com/?id=12345 now what i want is if there is an id parameter available in the url i want to append the same parameter to every url on that page . Opencart has a url library that generates url i am sure you all must be familiar with it too , i found a way to do what i want but it's working at just some random parts of the website like categories url's are generating with id parameter appended to it and other's dont .
here's what i tried so far
File : System/libray/url.php
here's the function
public function link($route, $args = '', $connection = 'NONSSL') {
if ($connection == 'NONSSL') {
$url = $this->url;
}else {
$url = $this->ssl;
}
$url .= 'index.php?route=' . $route;
if ($args) {
$url .= str_replace('&', '&', '&' . ltrim($args, '&'));
}
foreach ($this->rewrite as $rewrite) {
$url = $rewrite->rewrite($url);
}
if(isset($_GET['id']))
{
if(!empty($this->request->get['id']))
$url .= '&id='.$this->request->get['id'];
if(!empty($_GET['id']))
{
$url .= '&id='.$_GET['id'];
}
}
return $url;
}
The problem is that not everything uses this method to generate its URLs.
For example, anything to do with banners (e.g. the Carousel module) uses links that the admin sets manually in System->Design->Banners, so you would also need to edit the code for this too. The simplest and probably the correct way is to edit the data that the models spit out e.g.
model_design_banner->getBanner() becomes
public function getBanner($banner_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "banner_image bi LEFT JOIN " . DB_PREFIX . "banner_image_description bid ON (bi.banner_image_id = bid.banner_image_id) WHERE bi.banner_id = '" . (int)$banner_id . "' AND bid.language_id = '" . (int)$this->config->get('config_language_id') . "'");
if (isset($_GET['id'])) {
array_walk($query->rows, function(&$value) {
$value['link'] .= '&id=' . $_GET['id'];
});
}
return $query->rows;
}
It's either that, or edit the output in every single controller that uses this method.
That's just an example for banners, though. I don't recall off-hand which other modules will need to be edited, but if there's a particular one that's making you scratch your head, let me know and I'll give you another example to fix it.
in following function
public static function ToDepartment($departmentId, $page = 1)
{
$link = self::CleanUrlText(Catalog::GetDepartmentName($departmentId)) .
'-d' . $departmentId . '/';
if ($page > 1)
$link .= 'page-' . $page . '/';
return self::Build($link);
}
there is a line
$link = self::CleanUrlText(Catalog::GetDepartmentName($departmentId)) .
'-d' . $departmentId . '/';
I want to know will self:CleanUrlText() will be evaluated first or Catalog:GetDepartmentName will be evaluated first
if Catalog:GetDepartmentName is evaluated first then, I have a confusion,
what purpose does URL cleaning solve,
if I am visiting a page such as http://localhost/tshirtshop/visit###-the-zoo-d2/
then .htaccess is handling the URL ReWriting part,
where d2 will get converted to DepartmentId=2 and internally in all code logic I will use DepartmentId which is an INT , then why CleanURL function is required
The code is given here
1st: Catalog::GetDepartmentName
2nd: self::CleanUrlText