Can mpdf {PAGENO} display Persian characters? - pagination

Does mpdf has a setting somewhere to change the default numbering pattern?
I'm trying to use {PAGENO} in a footer, and it always shows 1,2,3 etc rather than ۱،۲،۳
For now I can workaround by adding a str_replace in the aliasReplace function of Mpdf.php, but that isn't very clean.

In the Mpdf.php file
Edit the aliasReplace() function
like this:
protected function aliasReplace($html, $PAGENO, $NbPgGp, $NbPg)
{
$persian = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$english = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ];
$PAGENO= str_replace($english, $persian, $PAGENO);
$NbPgGp= str_replace($english, $persian, $NbPgGp);
$NbPg= str_replace($english, $persian, $NbPg);
// Replaces for header and footer
$html = str_replace('{PAGENO}', $PAGENO, $html);
$html = str_replace($this->aliasNbPgGp, $NbPgGp, $html); // {nbpg}
$html = str_replace($this->aliasNbPg, $NbPg, $html); // {nb}
// Replaces for the body
$html = str_replace(mb_convert_encoding('{PAGENO}', 'UTF-16BE', 'UTF-8'), mb_convert_encoding($PAGENO, 'UTF-16BE', 'UTF-8'), $html);
$html = str_replace(mb_convert_encoding($this->aliasNbPgGp, 'UTF-16BE', 'UTF-8'), mb_convert_encoding($NbPgGp, 'UTF-16BE', 'UTF-8'), $html); // {nbpg}
$html = str_replace(mb_convert_encoding($this->aliasNbPg, 'UTF-16BE', 'UTF-8'), mb_convert_encoding($NbPg, 'UTF-16BE', 'UTF-8'), $html); // {nb}
// Date replace
$html = preg_replace_callback('/\{DATE\s+(.*?)\}/', [$this, 'date_callback'], $html); // mPDF 5.7
return $html;
}

Related

How to send customer renewal order to secondary email in Woocommerce subscription

I want to send the renewal order email to a secondary user email(which i have added in user-edit page using ACF).
I have tried many methods,woocommerce_subscription_payment_complete is also not working for me.
The following code i have tried:
add_action( 'woocommerce_order_status_completed', 'action_on_order_status_completed', 20, 2 );
function action_on_order_status_completed( $order_id, $order ){
$order = new WC_Order($order_id);
// Get the user ID from WC_Order methods
$user_id = $order->get_user_id(); // or $order->get_customer_id();
$secondary_recipient = get_field('secondary_email', 'user_'.$user_id );
$subscriptions_ids = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'any' ) );
// We get all related subscriptions for this order
foreach( $subscriptions_ids as $subscription_id => $subscription_obj )
if($subscription_obj->order->id == $order_id) break; // Stop the loop
// $subscription_objc = wcs_get_subscription($subscription_id);
//$userid = $subscription_objc->get_user_id();
$wc_emails = WC()->mailer()->get_emails();
$wc_emails['WCS_Email_Processing_Renewal_Order']->recipient = $secondary_recipient;
$wc_emails['WCS_Email_Processing_Renewal_Order']->trigger($subscription_id);
// $to = $secondary_recipient;
// $subject = "hi";
// $body =$user_id."end".$order_id."hhh".$subscription_id;
// $headers = array('Content-Type: text/html; charset=UTF-8');
// //$headers[] = 'Cc: sarun#cloudspring.in';
// wp_mail( $to, $subject, $body, $headers );
}
FYI:Email is sending if i use the commented wp_mail function.
We can add a secondary email as the recipient, Try the below code tested and it worked.
add_filter( 'woocommerce_email_recipient_customer_completed_renewal_order', 'my_email_recipient_filter_function', 10, 2);
function my_email_recipient_filter_function( $recipient, $order ) {
$user_id = $order->get_user_id(); // or $order->get_customer_id();
$secondary_recipient = get_field('secondary_email', 'user_'.$user_id );
if(! empty($secondary_recipient)){
$recipient = $recipient . ', '. $secondary_recipient;
return $recipient;
}else {
return $recipient;
}
}

How to extract initials from a name using Laravel

I have the method below that returns me a list of registered users:
$users = \App\Models\User::all();
It turns out that I would like to present only the initials of the names on that list.
Example:
Carlos Pereira do Nascimento = CN
Marcos Aurelio = MA
Sandra Lopes = SL
How could I do this by getting this data from the list?
Is it possible for me to treat this list by taking only the initials of the variable $ name?
You can use Laravel's accessor to get the initials modifying the following code:
public function getInitialsAttribute(){
$name = 'Carlos Pereira do Nascimento';
$name_array = explode(' ',trim($name));
$firstWord = $name_array[0];
$lastWord = $name_array[count($name_array)-1];
return $firstWord[0]."".$lastWord[0];
}
Now, you can get the initals using {{ $user->initials }}
Something like this should work:
$names = \App\Models\User::pluck('name');
$initials = [];
foreach($names as $name) {
$nameParts = explode(' ', trim($name));
$firstName = array_shift($nameParts);
$lastName = array_pop($nameParts);
$initials[$name] = (
mb_substr($firstName,0,1) .
mb_substr($lastName,0,1)
);
}
var_dump($initials);
Output:
array(1) {
["Carlos Pereira do Nascimento"]=>
string(2) "CN"
["Marcos Aurelio"]=>
string(2) "MA"
["Émile Durkheim"]=>
string(2) "ÉD"
}
Note the use of mb_substr as opposed to regular substr or a string index. This will return correct values for names starting with non ASCII characters like for example "Émile"
echo substr('Émile Durkheim', 0, 1);
// output: b"Ã"
echo 'Émile Durkheim'[0];
// output: b"Ã"
echo mb_substr('Émile Durkheim', 0, 1);
// output: É
For anyone looking for a simple, one-line, framework-agnostic solution:
$initials = preg_filter('/[^A-Z]/', '', $str);
I have just made the following PR to introduce a new Str::initials() String helper function in Laravel framework: https://github.com/laravel/framework/pull/40381
For those who already want to use this before it's accepted/merged, just extend Illuminate\Support\Str with this macro in your AppServiceProvider's boot() method:
Str::macro('initials', fn($value, $sep = ' ', $glue = ' ') => trim(collect(explode($sep, $value))->map(function ($segment) {
return $segment[0] ?? '';
})->join($glue)));
and then just use Str::initials('Foo Bar') or as an Eloquent accessor in your User model:
public function getInitialsAttribute(): string
{
return \Illuminate\Support\Str::initials($this->name);
}
so you can simply use something like {{ Auth::user()->initials }}.
Just Put this 2 line code
function initials($str) {
$ret = '';
foreach (explode(' ', $str) as $word)
$ret .= strtoupper($word[0]);
return $ret;
}
I just wanted to expand the answers above to help others looking to do the same.
Here's an example on what I did.
Create an Accessor in your user model:
public function getNameInitials()
{
$name = $this->name;
$name_array = explode(' ',trim($name));
$firstWord = $name_array[0];
$lastWord = $name_array[count($name_array)-1];
return mb_substr($firstWord[0],0,1)."".mb_substr($lastWord[0],0,1);
}
Then you can access it in your view as {{ $user->getNameInitials() }}
or you could easily access the initials of the authenticated user as follows {{ Auth::user()->getNameInitials() }}

place a marker on leaflet map from mongodb coordinates

I would like to place markers on a leaflet map but from a database,
I would like to save on mongodb the lat and long and show 'em like markers on my map, is that possible?
Create a request for example with JQuery Ajax:
$.ajax({url: "/your_data_provider.php", success: function(result){
//result = JSON.parse(result); // If your result is not a json Object.
// It depends on what your data looks like
//Example 1: Lat and Lng has a own field in the db
result.forEach(function(data){
var lat = data.lat;
var lng = data.lng;
var marker = L.marker([lat, lng]).addTo(map);
});
//Example 2: you have one geojson-data string field "geo" in db
// Before inserting in db create a featuregroup `var fg = L.featureGroup();`
// and add all markers to the group `marker.addto(fg);`.
// Then you can call `var datageo = fg.toGeoJSON();` and add this datageo to the db in the field "geo"
result.forEach(function(data){
var geo = data.geo;
L.geoJSON(geo).addTo(map);
});
//https://leafletjs.com/examples/geojson/
},
error: function(xhr){
alert("An error occured: " + xhr.status + " " + xhr.statusText);
}});
});
Also you need a data provider. You can create a REST-Api www.url.com/data/postions/ or calling directly for example a php file.
php file:
// I have never used MongoDB, you have to code your own request. I copied it.
<?php
header('Content-type:application/json;charset=utf-8');
try {
$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$listdatabases = new MongoDB\Driver\Command(["listDatabases" => 1]);
$res = $mng->executeCommand("admin", $listdatabases);
$databases = current($res->toArray());
$result = new array();
$x = 0;
foreach ($databases->databases as $el) {
$result[$x]['id'] = $el->id;
//Example 1:
$result[$x]['lat'] = $el->lat;
$result[$x]['lng'] = $el->lng;
//Example 2:
$result[$x]['geo'] = $el->geo;
$x++;
}
echo json_encode($result);
} catch (MongoDB\Driver\Exception\Exception $e) {
$error = new array();
$error['exception'] = $e->getMessage();
$error['line'] = $e->getLine();
echo json_encode($error);
}
?>

How to link custom results in Drupal

My first time here an a newbee in Drupal and programming .
So I have a problem I need to some help with.
function query_results($searchstring, $datefrom) {
$tidresult = db_query("SELECT tid FROM {term_data} WHERE LOWER(name) = '%s'", strtolower($searchstring));
$resultarray = array();
while ($obj = db_fetch_object($tidresult)) {
$tid = $obj->tid;
$noderesults = db_query("SELECT n.nid, n.title FROM {node} n
INNER JOIN {term_node} tn ON tn.nid = n.nid
WHERE tn.tid='%s'", $tid);
while ($nodeobj = db_fetch_object($noderesults)) {
$resultarray[$nodeobj->nid] = $nodeobj->title;
}
}
$header = array(
array('data' => 'Nr.'),
array('data' => 'Name'),
);
$rows = array();
$i = 0;
foreach($resultarray as $nid => $title) {
$i++;
$rows[] = array('data' =>
array(
$i,
$title,
),
);
}
$output = theme('table', $header, $rows);
print theme("page", $output);
}
It's driving me crazy , i dint put all of the search code but it takes taxonomy tags from the database ( you type in textbox that has autocomplete, '$searchstring' ) and date ( you choose a time line like one day , yesterday ect. , '$datefrom').
For example reasons lets say it looks like this example when you click search.
I can't post my one pictures but I just gives me the titles ( like above but the are not listed) that I cannot click to lead me to the content.
But I wont it to look like result that is like content ( story ) so you have a clickable Title and some description , like this click to see example
where it says lorem ipsum and that text belowe.
If it is hard to make like in the picture can someone show me just how to make( like in the first picture) the results that are non clickable titles into clickable links that lead me to the content.
To get linked titles you need to use the l() function.
looking at the code you provided, I am not entirely sure how you are getting any results since you save the titles in $resultArray but use $rows when rendering the table.
Unless, $rows is specified somewhere else, $resultarray[$nodeobj->nid] = $nodeobj->title; should become $rows[$nodeobj->nid] = $nodeobj->title;
To make it match your table header, you need to add another 'cell' for the number column
$rows[$nodeobj->nid] = array(
$count++,
l($nodeobj->title, 'node/'.$nodeobj->nid)
);
To provide the excerpt too, you need to join the node_revisions table and get either the body or teaser column, then add it to your rows like this:
$rows[$nodeobj->nid] = array(
$count++,
'<h2>'. l($nodeobj->title, 'node/'.$nodeobj->nid) .'</h2>'. $nodeobj->teaser
);
assuming you get the teaser.
EDIT
the previous answer still holds. You can also simplify the code a bit by processing $rows straight in the $noderesults loop.
function query_results($searchstring, $datefrom) {
$tidresult = db_query("SELECT tid FROM {term_data} WHERE LOWER(name) = '%s'", strtolower($searchstring));
$rows = array();
$count = 0;
while ($obj = db_fetch_object($tidresult)) {
$tid = $obj->tid;
$noderesults = db_query("SELECT n.nid, n.title FROM {node} n "
."INNER JOIN {term_node} tn ON tn.nid = n.nid "
."WHERE tn.tid='%s'", $tid);
while ($nodeobj = db_fetch_object($noderesults)) {
$rows[] = array(
++$count,
l($nodeobj->title, 'node/'. $nodeobj->title)
);
}
}
$header = array(
array('data' => 'Nr.'),
array('data' => 'Name'),
);
$output = theme('table', $header, $rows);
print theme("page", $output);
}
-OR-
move it all in one query (note: I did not get a chance to test this, but I usually get it right the first time):
function query_results($searchstring, $datefrom) {
$rows = array();
$count = 0;
$results = db_query("SELECT n.nid, n.title
FROM {node} n
INNER JOIN {term_node} tn ON tn.nid = n.nid
WHERE tn.tid IN (SELECT tid FROM {term_data} WHERE LOWER(name) = '%s')", strtolower($searchstring));
while ($nodeobj = db_fetch_object($results)) {
$rows[] = array(
++$count,
l($nodeobj->title, 'node/'. $nodeobj->title)
);
}
$header = array(
array('data' => 'Nr.'),
array('data' => 'Name'),
);
$output = theme('table', $header, $rows);
print theme("page", $output);
}

drupal form api checkboxes

I am using drupal form api and using checkboxes. I am getting problem in default checked values with it. following is the code snippet...
$result = db_query("SELECT nid, filepath FROM {content_type_brand}, {files} WHERE content_type_brand.field_brand_image_fid
= files.fid");
$items = array();
while ($r = db_fetch_array($result)) {
array_push($items, $r);
}
$options = array();
foreach( $items as $i ) {
$imagePath = base_path().$i['filepath'];
$options[$i['nid']] = '<img src="'.$imagePath.'"></img>';
}
$form['favorite_brands'] = array (
'#type' => 'fieldset',
'#title' => t('Favorite Brands'),
//'#weight' => 5,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['favorite_brands']['brands_options']
= array(
'#type' => 'checkboxes',
'#options' => $options,
'#default_value' => $options_checked,// $options_checked is an array similar to $options but having elements which need to be checked by default...
'#multicolumn' => array('width' => 3)
);
but values are not checked by default... can anyone help what I am missing??
Thanks
Your $options_checked array should not be in the same format as your $options array. Your $options array contains nid => img tag pairs. Your $options_checked array should simply contain the nid values of the options that should be checked by default:
$options_checked = array(8,17);

Resources