Below is some code I am working on for a navigation menu, if you are on a certain page, it will add a "current" css class to the proper tab.
I am curious if there is a better way to do this in PHP because it really seems like a lot of code to do such a simple task? My pages will also have a jquery library already loaded, would it be better to set the tab with jquery instead of PHP? Any tips appreciated
<?PHP
active_header('page identifier goes here'); //ie; 'home' or 'users.online'
function active_header($page_name)
{
// arrays for header menu selector
$header_home = array('home' => true);
$header_users = array(
'users.online' => true,
'users.online.male' => true,
'users.online.female' => true,
'users.online.friends' => true,
'users.location' => true,
'users.featured' => true,
'users.new' => true,
'users.browse' => true,
'users.search' => true,
'users.staff' => true
);
$header_forum = array('forum' => true);
$header_more = array(
'widgets' => true,
'news' => true,
'promote' => true,
'development' => true,
'bookmarks' => true,
'about' => true
);
$header_money = array(
'account.money' => true,
'account.store' => true,
'account.lottery' => true,
'users.top.money' => true
);
$header_account = array('account' => true);
$header_mail = array(
'mail.inbox' => true,
'mail.sentbox' => true,
'mail.trash' => true,
'bulletins.post' => true,
'bulletins.my' => true,
'bulletins' => true
);
// set variables if there array value exist
if (isset($header_home[$page_name])){
$current_home = 'current';
}else if (isset($header_users[$page_name])){
$current_users = 'current';
}else if (isset($header_forum[$page_name])){
$current_forum = 'current';
}else if (isset($header_more[$page_name])){
$current_more = 'current';
}else if (isset($header_money[$page_name])){
$current_money = 'current';
}else if (isset($header_account[$page_name])){
$current_account = 'current';
}else if (isset($header_mail[$page_name])){
$current_mail = 'current';
}
// show the links
echo '<li class="' . (isset($current_home) ? $current_home : '') . '"><em>Home</em></li>';
echo '<li class="' . (isset($current_users) ? $current_users : '') . '"><em>Users</em></li>';
echo '<li class="' . (isset($current_forum) ? $current_forum : '') . '"><em>Forum</em></li>';
echo '<li class="' . (isset($current_more) ? $current_more : '') . '"><em>More</em></li>';
echo '<li class="' . (isset($current_money) ? $current_money : '') . '"><em>Money</em></li>';
echo '<li class="' . (isset($current_account) ? $current_account : '') . '"><em>Account</em></li>';
echo '<li class="' . (isset($current_mail) ? $current_mail : '') . '"><em>Mail</em></li>';
}
?>
The two very large blocks of code at the bottom could be reduced drastically to a simple loop:
<?php
foreach (array('home', 'users', 'forum' /* ... */ ) as $item) {
$ar = "header_$item";
echo '<li class="', (isset($$ar[$page_name]) ? 'current' : '')
, '"><em>', ucword($item), '</em></li>';
}
?>
You should try not to print <li class=""> or something like that; it looks messy. I've moved the checking of whether this page or not is the one to highlight to a seperate function in case you end up changing the layout of $applicable_list.
<?php
function active_header($page) {
$applicable_list = array(
"home" => array("home"),
"users" => array(
"users.online", "users.online.male", "users.online.female", "users.online.friends",
"users.location", "users.featured", "users.new", "users.browse", "users.search", "users.staff"
),
"forum" => array("forum"),
"more" => array("widgets", "news", "promote", "development", "bookmarks", "about"),
"money" => array("account.money", "account.store", "account.lottery", "users.top.money"),
"account" => array("account"),
"mail" => array("mail.inbox", "mail.sentbox", "mail.trash", "bulletins.post", "bulletins.my", "bulletins")
);
$pages = array_keys($applicable_list);
function is_active_page($page, $category, $category_pages_list) {
return array_key_exists($category, $category_pages_list) && in_array($page, $category_pages_list[$category]);
}
foreach($pages as $key => $category) {
printf('<li%s><em>%s</em></li>' . "\n",
(is_active_page($page, $category, $applicable_list) ? ' class="current"' : ''),
ucwords($category)
);
}
}
?>
May as well throw in my lot. Output is restricted to match that given in the original question.
<?PHP
active_header('page identifier goes here'); //ie; 'home' or 'users.online'
function active_header($page_name)
{
// Unified array
$headers = array(
'Home' => array('home' => true),
'Users' => array(
'users.online' => true,
'users.online.male' => true,
'users.online.female' => true,
'users.online.friends' => true,
'users.location' => true,
'users.featured' => true,
'users.new' => true,
'users.browse' => true,
'users.search' => true,
'users.staff' => true
),
'Forum' => array('forum' => true),
'More' => array(
'widgets' => true,
'news' => true,
'promote' => true,
'development' => true,
'bookmarks' => true,
'about' => true
),
'Money' => array(
'account.money' => true,
'account.store' => true,
'account.lottery' => true,
'users.top.money' => true
),
'Account' => array('account' => true),
'Mail' => array(
'mail.inbox' => true,
'mail.sentbox' => true,
'mail.trash' => true,
'bulletins.post' => true,
'bulletins.my' => true,
'bulletins' => true
)
);
foreach($headers as $header => &$pages) {
echo '<li class="';
if(isset($pages[$page_name])) echo 'content';
echo '"><em>', $header, '</em></li>';
}
}
?>
I'm not a fan of mixing up the code with the output, but it'll do for example.
PHP hint of the day: Don't use string concatenation if you're just echoing a string
Rather than using the page names as array keys you could simply have arrays of the page names, and then compare using in_array($page_name, $array), rather than isset($array[$page_name]).
This should happily work alongside the alterations from #meager, and would allow the static bits of code at the top to shrink a little.
Consolidate your arrays, or put all that logic in another well-named function. My example consolidates the arrays.
// it's ugly, but at least the ugliness
// is confined to only _one_ array ;)
$map_pages_to_navitem = array(
'home' => 'home',
'users.online' => 'users',
'users.online.male' => 'users',
'users.online.female' => 'users',
'users.online.friends' => 'users',
'users.location' => 'users',
'users.featured' => 'users',
'users.new' => 'users',
'users.browse' => 'users',
'users.search' => 'users',
'users.staff' => 'users',
'forum' => 'forum',
'widgets' => 'more',
'news' => 'more',
'promote' => 'more',
'development' => 'more',
'bookmarks' => 'more',
'about' => 'more',
'account.money' => 'money',
'account.store' => 'money',
'account.lottery' => 'money',
'users.top.money' => 'money',
'account' => 'account'),
'mail.inbox' => 'mail',
'mail.sentbox' => 'mail',
'mail.trash' => 'mail',
'bulletins.post' => 'mail',
'bulletins.my' => 'mail',
'bulletins' => 'mail',
);
$current = $map_pages_to_navitem[$page_name];
echo '<li class="'.($current=='home')?'current':''.'"><em>Home</em></li>';
echo '<li class="'.($current=='users')?'current':''.'"><em>Users</em></li>';
echo '<li class="'.($current=='forum')?'current':''.'"><em>Forum</em></li>';
echo '<li class="'.($current=='more')?'current':''.'"><em>More</em></li>';
echo '<li class="'.($current=='money')?'current':''.'"><em>Money</em></li>';
echo '<li class="'.($current=='account')?'current':''.'"><em>Account</em></li>';
echo '<li class="'.($current=='mail')?'current':''.'"><em>Mail</em></li>';
Looking at the code, I also see the end result is to assign on <li> element a class attribute value. JavaScript will do this better than PHP.
So you could give each <li> an id and leave the assignment of the class attribute to JavaScript:
echo '<li id="home"><em>Home</em></li>';
echo '<li id="users"><em>Users</em></li>';
echo '<li id="forum"><em>Forum</em></li>';
echo '<li id="more"><em>More</em></li>';
echo '<li id="money"><em>Money</em></li>';
echo '<li id="account"><em>Account</em></li>';
echo '<li id="mail"><em>Mail</em></li>';
echo '<script type="text/javascript">';
echo 'document.getElementById("'.$current.'").className = "current";';
// you'll want to sanitize $current to avoid parse errors in your JS
echo '</script>'
Use a switch instead of extensive if/else for starters :-)
// set variables if there array value exist
if (isset($header_home[$page_name])){
$current_home = 'current';
}else if (isset($header_users[$page_name])){
$current_users = 'current';
}else if (isset($header_forum[$page_name])){
$current_forum = 'current';
}else if (isset($header_more[$page_name])){
$current_more = 'current';
}else if (isset($header_money[$page_name])){
$current_money = 'current';
}else if (isset($header_account[$page_name])){
$current_account = 'current';
}else if (isset($header_mail[$page_name])){
$current_mail = 'current';
}
You can use variables variable ( http://www.php.net/manual/en/language.variables.variable.php ), foreach and break to reduce this part of function
I don't see any compelling reason to change your original code. It's very easy to read and understand, and easy enough to modify. I also don't think there's any reason to use Javascript to set the tab indicator. By using PHP, you cater to people who have javascript disabled, and I like to save Javascript for when it's truly needed.
If not changing to "return htmlcode" from "printing htmlcode", i would at least add a second parameter for that.
Related
I am at beginner level of drupal trying to Overriding the third party uc_cart_uc_cart_pane function into my own custom function custom_session_uc_cart_pane but it is duplicating the form or result
Here is sample functions
/**
* Implements hook_uc_cart_pane().
*/
function uc_cart_uc_cart_pane($items) {
$body = array();
if (!is_null($items)) {
$body = drupal_get_form('uc_cart_view_form', $items) + array(
'#prefix' => '<div id="cart-form-pane">',
'#suffix' => '</div>',
);
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
function custom_session_uc_cart_pane($items){
$iframe = multi_domain_iframe();
// echo "<pre>";
// print_r($items);
// exit;
$pre_suf_fix = array(
'#prefix' => '<div id="cart-form-pane1">',
'#suffix' => '</div>'.$iframe,
);
$body = array() + $pre_suf_fix;
if (!is_null($items)) {
$body = drupal_get_form('custom_session_view_form', $items) + $pre_suf_fix;
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
any thing which i am missing.
if you want to change some thing specifically for a form you can use
hook_form_alter
you do not need to override the function.
Thanks
Rather than using a plug-in I am in the process of creating my own schema markup for a home page on a WordPress site which makes use of Advananced Custom Fields (ACF) for some of the content relevant to this challenge. My aim is to give me a little more granular control over what is output and as a little personal challenge :)
So far I have successfully created a basic schema, but I have become stuck where I need to create a nested entity for a list of services.
currently I have this in my functions.php file:
function schema() {
$schema = array(
'#context' => "http://schema.org",
'#type' => "ProfessionalService",
'name' => get_bloginfo('name'),
'url' => get_home_url(),
// ... and so on
);
if ( have_rows('services_list') ) {
$schema['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($schema['itemListElement'], $services);
endwhile;
}
echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');
Result:
{
"#context":"http:\/\/schema.org",
"#type":"ProfessionalService",
"name":"Name of Company",
"url":"http:\/\/www.whatever.com",
and so on...
"itemListElement": [
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service One"
}
},
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service Two"
}
},
... more services
]
}
This resulting markup is great, but I need to nest the itemListElement so that it outputs like so:
"hasOfferCatalog": {
"#type": "OfferCatalog",
"name": "Some Services",
"itemListElement": [
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service One"
}
},
{
"#type":"Offer",
"itemOffered": {
"#type":"Service",
"name":"Service Two"
}
},
... more services
I can't for the life of me work out how this is done. My current best effort is to add it like so:
if ( have_rows('services_list') ) {
'hasOfferCatalog' => array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
$schema['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($schema['itemListElement'], $services);
endwhile;
)
}
However this is not working at all. If anyone can point me in the right direction to the nested entities working in this context I'd be really grateful.
I did eventually manage to solve my issue. I never got around to posting this at he time, but since here's been a little interest here's what I did.
My 'best effort' was almost there, but I needed to make a few small adjustments. Sadly I sorted this out sometime ago and I forget the resource I used to put things right, but I hope this might be of help to someone else.
if ( have_rows('services_list') ) {
$schema['hasOfferCatalog'] = array();
$catalog = array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
);
if ( have_rows('services_list') ) {
$catalog['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($catalog['itemListElement'], $services);
endwhile;
array_push($schema['hasOfferCatalog'], $catalog);
}
}
Fr a little bit of context I have this all placed in my functions.php file and is put together like so:
function schema() {
$schema = array(
'#context' => "http://schema.org",
'#type' => "ProfessionalService",
'name' => get_bloginfo('name'),
'url' => get_home_url(),
'telephone' => '+00 0000 00000',
'address' => array(
'#type' => 'PostalAddress',
'streetAddress' => 'XXXXX',
'postalCode' => 'XXX XXX',
'addressLocality' => 'XXXXXX',
'addressRegion' => 'XXXXXXX',
'addressCountry' => 'XXXXXXXXXXXX'
),
'logo' => get_stylesheet_directory_uri() . '/path/to/your/image.svg',
'image' => get_stylesheet_directory_uri() . '/path/to/your/image.svg'
);
if ( have_rows('services_list') ) {
$schema['hasOfferCatalog'] = array();
$catalog = array(
'#type' => 'OfferCatalog',
'name' => 'Tree Surgery'
);
if ( have_rows('services_list') ) {
$catalog['itemListElement'] = array();
while (have_rows('services_list')) : the_row();
$services = array(
'#type' => 'Offer',
'itemOffered' => array (
'#type' => 'Service',
'name' => get_sub_field('service')
)
);
array_push($catalog['itemListElement'], $services);
endwhile;
array_push($schema['hasOfferCatalog'], $catalog);
}
}
echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');
It seems to do the job.
On my classes/PaymentModule.php I have declared '{message}' => $customer_message (between other vars) but still my customers see Wiadomość: {message}
in mails which they recieved.
What do I wrong? Maybe declare {message} var in PaymentModule.php is not enough?
UDPATE:
this is standard PaymentModule.php code in Prestashop 1.6.2.1 with added {message} variable:
$customer_message = $order->getFirstMessage();
$data = array(
'{firstname}' => $this->context->customer->firstname,
'{lastname}' => $this->context->customer->lastname,
'{email}' => $this->context->customer->email,
'{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"),
'{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"),
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, '<br />', array(
'firstname' => '<span style="font-weight:bold;">%s</span>',
'lastname' => '<span style="font-weight:bold;">%s</span>'
)),
'{invoice_block_html}' => $this->_getFormatedAddress($invoice, '<br />', array(
'firstname' => '<span style="font-weight:bold;">%s</span>',
'lastname' => '<span style="font-weight:bold;">%s</span>'
)),
'{delivery_company}' => $delivery->company,
'{delivery_firstname}' => $delivery->firstname,
'{delivery_lastname}' => $delivery->lastname,
'{delivery_address1}' => $delivery->address1,
'{delivery_address2}' => $delivery->address2,
'{delivery_city}' => $delivery->city,
'{delivery_postal_code}' => $delivery->postcode,
'{delivery_country}' => $delivery->country,
'{delivery_state}' => $delivery->id_state ? $delivery_state->name : '',
'{delivery_phone}' => ($delivery->phone) ? $delivery->phone : $delivery->phone_mobile,
'{delivery_other}' => $delivery->other,
'{invoice_company}' => $invoice->company,
'{invoice_vat_number}' => $invoice->vat_number,
'{invoice_firstname}' => $invoice->firstname,
'{invoice_lastname}' => $invoice->lastname,
'{invoice_address2}' => $invoice->address2,
'{invoice_address1}' => $invoice->address1,
'{invoice_city}' => $invoice->city,
'{invoice_postal_code}' => $invoice->postcode,
'{invoice_country}' => $invoice->country,
'{invoice_state}' => $invoice->id_state ? $invoice_state->name : '',
'{invoice_phone}' => ($invoice->phone) ? $invoice->phone : $invoice->phone_mobile,
'{invoice_other}' => $invoice->other,
'{order_name}' => $order->getUniqReference(),
'{date}' => Tools::displayDate(date('Y-m-d H:i:s'), null, 1),
'{carrier}' => ($virtual_product || !isset($carrier->name)) ? Tools::displayError('No carrier') : $carrier->name,
'{payment}' => Tools::substr($order->payment, 0, 32),
'{products}' => $product_list_html,
'{products_txt}' => $product_list_txt,
'{discounts}' => $cart_rules_list_html,
'{discounts_txt}' => $cart_rules_list_txt,
'{total_paid}' => Tools::displayPrice($order->total_paid, $this->context->currency, false),
'{total_products}' => Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $order->total_products : $order->total_products_wt, $this->context->currency, false),
'{total_discounts}' => Tools::displayPrice($order->total_discounts, $this->context->currency, false),
'{total_shipping}' => Tools::displayPrice($order->total_shipping, $this->context->currency, false),
'{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $this->context->currency, false),
'{message}' => $customer_message,
'{total_tax_paid}' => Tools::displayPrice(($order->total_products_wt - $order->total_products) + ($order->total_shipping_tax_incl - $order->total_shipping_tax_excl), $this->context->currency, false));
In order_conf.html:
...
Wiadomość: {message}
....
ou should use below function if not already using it.
Example:
$id_lang = (int)$this->context->language->id;
$heading = Mail::l('Message Received', (int)$id_lang);
Mail::Send(
(int)$id_lang,
'order_conf',
$heading,
$data,
$this->context->customer->email,
null,
null,
$this->context->shop->name,
null,
null,
_PS_MODULE_DIR_.'mymodule/mail/',
false,
1
);
mail template should be located in 'mymodule/mail/en/order_conf.html' make languages directories according to your languages like /en , /fr, /nl
With Prestashop 1.7, I’ve tested with
'{message}' => 'hello',
And it displays in email : hello
Are you sure you have something in $customer_message ?
It can be more complicated with some variables. Have a look at $product_list_html
You will see it is an array and there is :
$product_list_html = $this->getEmailTemplateContent('order_conf_product_list.tpl', Mail::TYPE_HTML, $product_var_tpl_list);
It uses an other template to build the list of product (order_conf_product_list.tpl)
I know that post is 3 years old but the solution is not using
$customer_message
but
$customer_message->message
I am trying to write a script that imports my categories from a XML into prestashop. There is one problem, the script does not add the category and stops working when it reaches ->add();
I'm trying to find the problem, but I really don't know what to do anymore.
Here is my script:
if ($cat == "") {
$category = new Category;
$category->active = 1;
$category->id_parent = 3;
$category->name[1] = $product->category_name;;
$category->link_rewrite[1] = Tools::link_rewrite($product_xml->category_name);
echo "<br />name of new category = $product->category_name <br /> <br />";
$category->add();
$G_array[] = $category->id;
$G_cat = $G_cat . "\r\n" . 'Category: ' . $category->name[1].' with the id: '.$category->id.' Created'; //adding new category to var, to be displayed at the index page.
}else{
I am using prestashop 1.6, I hope that someone can explain to me what I am doing wrong..
It works for me
$Category = new Category();
$Category->name = [(int)Configuration::get('PS_LANG_DEFAULT') => 'nome'];
$Category->link_rewrite = [(int)Configuration::get('PS_LANG_DEFAULT') => 'link_rewrite'];
$Category->description = [(int)Configuration::get('PS_LANG_DEFAULT') => 'descrizione'];
$Category->active = 1;
$Category->id_parent = 3;
$Category->add();
for update
$Category = new Category($id_category);
$Category->name = [(int)Configuration::get('PS_LANG_DEFAULT') => 'nome'];
$Category->link_rewrite = [(int)Configuration::get('PS_LANG_DEFAULT') => 'link_rewrite'];
$Category->description = [(int)Configuration::get('PS_LANG_DEFAULT') => 'descrizione'];
$Category->active = 1;
$Category->id_parent = 3;
$Category->update();
you can check if the category is valid with this function
Validate::isLoadedObject($Category) //true or false
remember prestashop checks whether the values of the changes are valid
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
isCatalogName, isLinkRewrite, isCleanHtml these are controls insertion
You must delete character not valid in link_rewrite. Delete punctuation marks, vowels with accents, brackets, ...
In prestashop code there is a function to convert a string to link_rewrite.
Rarely does the array starts at 1... Change it:
$category->name[0]=...
$category->link_rewrite[0]=...
PD: The best way to manipulate data in prestashop is the Rest API
In Yii,Iam using yii-jpegcam webcam extension used for taking photos in my application and it works fine with the following url format
index.php?r=user/newphoto
But my application is in "/" format (index.php/user/newphoto). So this extension not working with my url format. How it can be solved?
Extension Link used : http://www.yiiframew...on/yii-jpegcam/
http://www.yiiframework.com/extension/yii-jpegcam/
And my view code is :
<?php $onBeforeSnap = "document.getElementById('upload_results').innerHTML = '<h1>Uploading...</h1>';";
$completionHandler = <<<BLOCK
if (msg == 'OK') {
document.getElementById('upload_results').innerHTML = '<h1>OK! ...redirecting in 3 seconds</h1>';
// reset camera for another shot
webcam.reset();
setTimeout(function(){window.location = "index.php?r=user/index";},3000);
}
else alert("PHP Error: " + msg);
BLOCK;
$this->widget('application.extensions.jpegcam.EJpegcam', array(
'apiUrl' => 'index.php?r=user/jpegcam.saveJpg',
'shutterSound' => false,
'stealth' => true,
'buttons' => array(
'configure' => 'Configure',
'takesnapshot' => 'Take Snapshot!'
),
'onBeforeSnap' => $onBeforeSnap,
'completionHandler' => $completionHandler
)); ?>
If urlManager enabled in config, you should change apiUrl value with createUrl method :
$this->widget('application.extensions.jpegcam.EJpegcam', array(
'apiUrl' => Yii::app()->urlManager->createUrl('index.php/user/jpegcam.saveJpg'),
'shutterSound' => false,
'stealth' => true,
'buttons' => array(
'configure' => 'Configure',
'takesnapshot' => 'Take Snapshot!'
),
'onBeforeSnap' => $onBeforeSnap,
'completionHandler' => $completionHandler
));