News:

You may pay someone to create your store, or you visit our seminar and become a professional yourself with the silver certification

Main Menu

php code for showing customer country

Started by Frans D, March 23, 2015, 11:55:54 AM

Previous topic - Next topic

Frans D

VM version 3.0.6.2.

I am trying to show a customers country within a php file.

With the code:
<?php echo $this->orderDetails['details']['BT']->virtuemart_country_id?>
The right country ID number is shown, however not the country name itself.
Does anyone know how to complete the code, so that is shows the right country name?

Thanks in advance.

PRO

THis might work

shopfunctions::getCountryByID($this->orderDetails['details']['BT']->virtuemart_country_id)

if not, here is the function, I do not understand the 2nd parameter

   /**
    * Return the countryname or code of a given countryID
    *
    * @author Oscar van Eijk
    * @access public
    * @param int $id Country ID
    * @param char $fld Field to return: country_name (default), country_2_code or country_3_code.
    * @return string Country name or code
    */
   static public function getCountryByID ($id, $fld = 'country_name') {

      if (empty($id)) {
         return '';
      }

      $id = (int)$id;
      $db = JFactory::getDBO ();

      $q = 'SELECT `' . $db->escape ($fld) . '` AS fld FROM `#__virtuemart_countries` WHERE virtuemart_country_id = ' . (int)$id;
      $db->setQuery ($q);
      return $db->loadResult ();
   }

Frans D

Thanks for trying to help out.

I've tried the code, but get a white page in the admin, when I use it.

Searching further I found a more extended code, but I am not sure which part I need.

// Translate the value from ID to name
$_return['fields'][$_fld->name]['virtuemart_country_id'] = (int)$_return['fields'][$_fld->name]['value'];
$db = JFactory::getDBO ();
$q = 'SELECT * FROM `#__virtuemart_countries` WHERE virtuemart_country_id = "' . (int)$_return['fields'][$_fld->name]['value'] . '"';
$db->setQuery ($q);
$r = $db->loadAssoc();
if($r){
$_return['fields'][$_fld->name]['value'] = !empty($r['country_name'])? $r['country_name']:'' ;
$_return['fields'][$_fld->name]['country_2_code'] = !empty($r['country_2_code'])? $r['country_2_code']:'' ;
$_return['fields'][$_fld->name]['country_3_code'] = !empty($r['country_3_code'])? $r['country_3_code']:'' ;
} else {
vmError('Model Userfields, country with id '.$_return['fields'][$_fld->name]['value'].' not found');
}
} else {
$_return['fields'][$_fld->name]['value'] = '' ;
$_return['fields'][$_fld->name]['country_2_code'] = '' ;
$_return['fields'][$_fld->name]['country_3_code'] = '' ;
}

//$_return['fields'][$_fld->name]['value'] = vmText::_(shopFunctions::getCountryByID($_return['fields'][$_fld->name]['value']));
//$_return['fields'][$_fld->name]['state_2_code'] = vmText::_(shopFunctions::getCountryByID($_return['fields'][$_fld->name]['value']));


PRO

you tried this?


shopfunctions::getCountryByID($this->orderDetails['details']['BT']->virtuemart_country_id)


OR the full function i posted?
posting the full function is not the right way, it is already in the vmart application

GJC Web Design

QuoteI do not understand the 2nd parameter

you could also get the 2 or 3 code by e.g

shopfunctions::getCountryByID($this->orderDetails['details']['BT']->virtuemart_country_id,'country_2_code')
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

Frans D

#5
Quoteyou tried this?

Yes I did.
The thing is; That the data is called from a table were there is only the virtuemart_country_id stated, so it is impossible to fetch the country_name from that same DB table.
So to get it working, the Country ID to name data should be called from the virtuemart_countries table.

It is mend for the invoice_order.php

I have changed it drastically, to make the pdf invoice look like a real invoice.
It is finished, except for the country name.

I have attached the adapted invoice_order.php 

GJC Web Design

QuoteThat the data is called from a table were there is only the virtuemart_country_id stated, so it is impossible to fetch the country_name from that same DB table

your sending a country id to a helper function getCountryByID()  - has nothing to do with the above .

This is the function you use to get a country name

it's exactly the same as

function getCountryName($virtuemart_country_id) {
   $db = JFactory::getDBO();
   $q = 'SELECT country_name FROM `#__virtuemart_countries` '
      . 'WHERE `virtuemart_country_id` = ' . $virtuemart_country_id;      
   $db->setQuery($q);
   $country_code = $db->loadResult();
       return $country_name;
      }
   

   $country_name = getCountryName($this->orderDetails['details']['BT']->virtuemart_country_id);
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

Frans D

#7
I am not a coder and am trying to make it work, by seeking for codes within other files, so I can use them in the php file.
I managed to do that with most of the things I want to show and have on certain positions, however I cannot get it working with the country name.
Can you perhaps tell me how I should implement that code, into the position I want to have it at the invoice_order.php 
I have attached it within my previous post.

Edit: it's working now, I forgot to add the "echo" part.

<?php echo shopfunctions::getCountryByID($this->orderDetails['details']['BT']->virtuemart_country_id?>

Thanks a lot for your help, the both of you.

PRO


Frans D

components/com_virtuemart/views/invoice/tmpl/invoice_order.php

It's the top half of the invoice and also delivery note, which takes care of data like the address field, date, invoice number etc.
Halfway invoice_items.php is used to put the ordered items etc. into the same documents and there is also invoice_history.php which appears at the bottom.

But I am probably telling you things, you already know. ;)

I am aware that the way I did it now, the address shown, will always be the invoice address.
In a more ideal world, each address field would change, according to were its for used; invoice or delivery note.
Fields like the invoice number, changes already due to calling the delivery note language string, when the delivery note is created.
But I am happy with this already, we will just enclose the invoice with a send order.

Milbo

Frans D, you make your life really hard. There are address fields for a reason! If you wanna invent the wheel again, no problem. Anywhere we use the fields, fields keep the country id and name.

Interesting, I just notice that both functions getCountryByID and getCountryIDByName should be in the country model.



Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Frans D

Hi Milbo,

Please don't get me wrong because I do appreciate very much everything the VM crew does.
But the pdf invoice VM creates is very chaotic and has some faults.
The thing with the standard address field, is that you cannot alter the positions of the address data, or can get rid of some data you don't want.
Now the invoice address data is called with;

foreach ($this->userfields['fields'] as $field) {
      if (!empty($field['value'])) {
          echo '<tr><td class="key">' . $field['title'] . '</td>'
          . '<td>' . $field['value'] .

It shows;
Email
Company name
First name
Last name
Street
Zip
City
Country
Additional user fields

I cannot get rid of certain data, neither can I position them elsewhere.
In the (lot) older VM versions you had separate field tags which you could position everywhere you liked, for example {phpShopBTStreet1} etc.
I understand that it is a lot easier, to call the address data with the shortest code possible throughout several php files, but it makes it very hard to customize the files to someone else's need.

This was the very first pdf invoice, I got from a test order:



Loads of data at the invoice_order.php
A lot of things I don't want on an invoice and others I want at another position.

The invoice_items.php show sums, that just don't add up and also extra info fields, which are already in the top half of the invoice (invoice_order.php).

So that why I rebuild it with a lot of single tags for calling data, I can customize the invoice to my likings and make it look a lot cleaner.
I also removed some fields from the invoice_items.php so the sums add up.




PRO

Frans, you can. You just have not thought through the logic of what you have to do.

Here is the order email code I use to format the address etc. the way I want it.

  <?php

       foreach ($this->userfields['fields'] as $field) {
      if (!empty($field['value'])) {
      if ($field['name']=='virtuemart_country_id') continue;
            if ($field['name']=='phone_1') {$field['value'] = ltrim($field['value'], '1');
            $field['value'] = str_replace( '-', '.', $field['value'] );}
            if ($field['name']=='virtuemart_state_id'){$stateId= shopfunctions::getStateIDByName ($field['value']);
         $field['value'] =shopfunctions::getStateByID ($stateId, 'state_2_code');}
         ?>
              <span class="values vm2<?php echo '-' . $field['name'] ?>" ><?php echo $this->escape($field['value']) ?></span>
         <?php if (($field['name'] == 'first_name') OR ($field['name'] =='zip') OR ($field['name'] =='company') OR ($field['name']=='phone_1') OR ($field['name']=='email') OR ($field['name']=='address_1') OR ($field['name']=='address_2')  ) { ?>
             <br class="clear" />
             <?php
         }
         if ($field['name']=='city'){echo ' ,';}
          }
      
       }
       ?>


IF YOU NOTICE:
This code
if ($field['name']=='virtuemart_country_id') continue;

SKIPS the country

If you notice
here
<span class="values vm2<?php echo '-' . $field['name'] ?>" ><?php echo $this->escape($field['value']) ?></span>
is where the field is echo'd

THEN: if you notice:Right after the code above
this code chooses when to add a "break"

         <?php if (($field['name'] == 'first_name') OR ($field['name'] =='zip') OR ($field['name'] =='company') OR ($field['name']=='phone_1') OR ($field['name']=='email') OR ($field['name']=='address_1') OR ($field['name']=='address_2')  ) { ?>
             <br class="clear" />
             <?php
         }



Then this code here. adds a comma between the city & state   ie.  Tampa, FL
if ($field['name']=='city'){echo ' ,';}


ALSO: you can do single values in other places in the file by doing.


<?php
       foreach ($this->userfields['fields'] as $field) {
       if ($field['name']!='MY-FIELD') continue;
              <span class="values vm2<?php echo '-' . $field['name'] ?>" ><?php echo $this->escape($field['value']) ?></span>
       }
       ?>

Just change MY-FIELD to the correct field



Now I know your file is still using a table, and mine does not anymore.
But, you should be able to use the references above to help get to where you need.


Milbo

Wow, Pro :-)

But I must admit it is not a nice way. I like the ideas of Frans and I get more and more an idea how todo write it a nice generic way. Frans D, pm me.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Frans D

#14
@ Pro; Thanks a lot for explaining this.
I can't code, for me it is usually a matter of searching through php files for useable codes.
So it makes it a lot harder to understand the codes.
And trying out all these codes is pretty time consuming; adapting the invoice_order, overwrite it at the server, making a test order, checking the backend how the pdf looks (or in case of an code error, causing a white screen).
However like you try to point out, a lot of things in the codes are logic and understandable.

Since the invoice_order.php is used for both invoice and delivery note, it would be very convenient if the address field would change according to which pdf is created in the backend.
The invoice_order.php has already one code present which takes care of what needs to be shown if it's an invoice or a delivery note;

<?php
if ($this->doctype == 'invoice') {
  if ($this->invoiceNumber) { ?>
<h1><?php echo vmText::_('COM_VIRTUEMART_INVOICE').' '.$this->invoiceNumber; ?> </h1>
<?php }
} elseif ($this->doctype == 'deliverynote') { ?>
<h1><?php echo vmText::_('COM_VIRTUEMART_DELIVERYNOTE'); ?> </h1>
<?php } elseif ($this->doctype == 'confirmation') { ?>
<h1><?php echo vmText::_('COM_VIRTUEMART_CONFIRMATION'); ?> </h1>

<?php } ?>

It shows either Invoice (language string) followed by the invoice number or just the packaging note language string.
So if I would want to use it for automatically changing the address, weather it is appearing in the invoice or delivery note.
Would a code like this be in the right direction, or complete off?

<?php
if ($this->doctype == 'invoice') {
  <?php echo $this->orderDetails['details']['BT']->company; ?>
<?php }
} elseif ($this->doctype == 'deliverynote') { ?>
<?php echo $this->orderDetails['details']['ST']->company; ?>
   <?php   if (!empty($field['value'])) {
          echo $this->orderDetails['details']['BT']->company; ?>
  <?php } ?>

@ Milbo; PM send.