Jump to content
adrianmak

pages created by api could not able to retrieve from other languages

Recommended Posts

My site has three language, default, chs, eng. Default language is cht (traditional chinese)

I have an order template (no output template). Structure look like

post-2272-0-77072600-1461231407_thumb.pn

An order will be created after a successful paypal transaction has been made.

When I'm on default language, the order creation is working properly.

However, if I switched to chs or eng

The order number field i.e. title field cannot be inserted. I just saw an empty title field. All other fields are populated values properly, except the order number

Here is my page creation code

$p = new Page();
$orderByUser = $user;
$p->template = "order";
$counter_name = $order_number_prefix . date('Y');
$number = $this->modules->get('DatabaseCounters')->next($counter_name, 1, 5000);
$ordernumber = $counter_name . '-' . sprintf("%06u", $number);
$p->title = $ordernumber;
$p->member = $orderByUser;
$p->payment_method = $session->get("payment_method");
$p->order_time = $session->get("order_time");
$p->paypal_transaction_id = $session->get("paypal_transaction_id");
foreach($session->get("cart_item") as $cart_item) {
    // create order items
    $item = $p->order_items->getNew();
    $item->product_id = $cart_item['id'];
    $item->product_name = $cart_item['name'];
    $item->product_price = $cart_item['price'];
    $item->product_quantity = $cart_item['quantity'];
    $item->save();
    $p->order_items->add($item);
    $transaction_amount += ($cart_item['price'] * $cart_item['quantity']);
}
$p->transaction_amount = $transaction_amount;
$p->of(false);
$p->save();

Share this post


Link to post
Share on other sites

I think you need to specify the language.

Taken from an import script from a multi-lingual site I built, it would be done a bit like this:

$def = $wire->languages->get("default");
$chs = $wire->languages->get("chs");
$eng = $wire->languages->get("eng");
// ...
$p->title->setLanguageValue($def, $ordernumber);
$p->title->setLanguageValue($chs, null);
$p->title->setLanguageValue($eng, null);

Share this post


Link to post
Share on other sites

In this case, I would actually suggest to create a new field for the order number, since it complicates things to have a multilanguage field for this value.

And as a multilanguage title doesn't make much sense for an order, you could make the title not required and hidden (under the visibility setting) for this specific template.

  • Like 2

Share this post


Link to post
Share on other sites

In this case, I would actually suggest to create a new field for the order number, since it complicates things to have a multilanguage field for this value.

And as a multilanguage title doesn't make much sense for an order, you could make the title not required and hidden (under the visibility setting) for this specific template.

Thank you for your suggestion

Share this post


Link to post
Share on other sites

As ESRCH suggested, I added another text field (not the multilanguage text field) for order number

However I can only hide the original text field from ui and cannot deleted it (pw nature, title field is compulsory for all template)

and the text field is configured as PageTitleLanguage (used by other page templates), then the order template is also a multilanguage .

So I have to make other two languages active before saving.

Here is my updated code

// Add a customer order in database
$p = new Page();
$orderByUser = $user;
$p->template = "order";
$counter_name = $order_number_prefix . date('Y');
$number = $this->modules->get('DatabaseCounters')->next($counter_name, 1, 5000);
$ordernumber = $counter_name . '-' . sprintf("%06u", $number);
$p->order_number = $ordernumber;
$p->member = $orderByUser;
$p->payment_method = $session->get("payment_method");
$p->order_time = $session->get("order_time");
$p->paypal_transaction_id = $session->get("paypal_transaction_id");
foreach($session->get("cart_item") as $cart_item) {
    // create order items
    $item = $p->order_items->getNew();
    $item->product_id = $cart_item['id'];
    $item->product_price = $cart_item['price'];
    $item->product_quantity = $cart_item['quantity'];
    $item->save();
    $p->order_items->add($item);
    $transaction_amount += ($cart_item['price'] * $cart_item['quantity']);
}
$p->transaction_amount = $transaction_amount;
$p->of(false);
foreach($languages as $lang) {
    if($lang->isDefault()) continue;
        $p->set("status$lang", 1);
    $p->save();
}

I found that the order_items (repeater field) does not display on English language until I edit that order at the back-end and save once again.

There is no issue on default and chs language

Here is a recorded youtube to show the issue I described.

Share this post


Link to post
Share on other sites

Since the order items are displayed in two languages, the order items must be created.

Can you show the code where you retrieve and then display the order items on the front-end (after clicking on the order in the dashboard)? Since the order item is completely skipped in English (not just displayed without text), it seems like you are using a filter in the loop (something like "if (!$product) continue;"), and there is a problem with this filter in English. If you echo $order->order_items->count(), does it show 0 (nothing) or 1?

Also, is there a reason why you use a text field rather than a page field for the product_id on the order_items repeater?

Finally, in the code that you pasted above, you wrote $p->save() within the foreach loop. I think you should be able to  do that only once under the loop.

Share this post


Link to post
Share on other sites

This is the template to list all the order that current $user had made

<?php

$_heading = __("交易記錄"); // Order history
$_tbl_header_1 = __("訂單號碼"); // Order number
$_tbl_header_2 = __("PayPal交易號碼"); // paypal transaction id
$_tbl_header_3 = __("交易日期"); // order date
$_tbl_header_4 = __("交易金額"); // order amount
$_no_history = __("沒有交易記錄"); // No order history

$content = '';
$out = '';
$edit = '';
$header_image = '';
$rowcount = 1;
$orders = '';

$breadcrumb = breadcrumb($page->id);

if($user->isSuperuser() || $user->hasRole("editor"))
    $selector = "template=order, sort=-order_time";
else $selector = "template=order, member={$user}, sort=-order_time";

$orders = $pages->find($selector);

$out .= "<div class='row clearfix'>";
$out .= "<div class='col-md-12'>";
$out .= "<h2>{$_heading}</h2>";

if($orders) {
$out .= "<table class='table table-bordered table-condensed table-striped '>";
$out .= "<thead>";
$out .= "<tr>";
$out .= "<th>#</th>";
$out .= "<th class='center'>{$_tbl_header_1}</th>";
$out .= "<th class='center'>{$_tbl_header_2}</th>";
$out .= "<th class='center'>{$_tbl_header_3}</th>";
$out .= "<th class='center'>{$_tbl_header_4}</th>";
$out .= "</tr>";
$out .= "</thead>";
$out .= "<tbody>";



foreach($orders as $order) {

    // Order detail modal popup
    $out .= "<div class='modal fade' id='orderDetail-{$order->id}' tabindex='-1' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true'>";
    $out .= "<div class='modal-dialog'>";
    $out .= "<div class='modal-content'>";
    $out .= "</div> <!-- /.modal-content -->";
    $out .= "</div> <!-- /.modal-dialog -->";
    $out .= "</div> <!-- /.modal -->";

    $out .= "<tr>";
    $out .= "<td class='center'>{$rowcount}</td>";
    $out .= "<td class='center'><a data-toggle='modal' data-target='#orderDetail-{$order->id}' href='".$pages->get(1208)->url."?id=".$order->id."'>{$order->order_number}</a></td>";
    $out .= "<td class='center'>{$order->paypal_transaction_id}</td>";
    $out .= "<td class='center'>".date('d-M-Y', $order->order_time)."</td>";
    $out .= "<td class='center'>".number_format($order->transaction_amount)."</td>";
    $out .= "</tr>";
    $rowcount++;
}

$out .= "</tbody>";
$out .= "</table>";
$out .= "</div>";
$out .= "</div>";

$content .= $out;
} else {
    $content .= $_no_history;
}

$out .= "<td class='center'><a data-toggle='modal' data-target='#orderDetail-{$order->id}' href='".$pages->get(1208)->url."?id=".$order->id."'>{$order->order_number}</a></td>";

The is 1208 is the page id of a order detail modal box, passing order is to this template

This is the modal box order-details.php template

<?php

// translation string
$_order_detail_text_1 = __("訂單號碼"); // Order number
$_order_detail_text_2 = __("PayPal交易號碼"); // PayPal transaction id
$_order_detail_text_3 = __("交易日期"); // Order time
$_order_detail_text_4 = __("交易金額"); // transaction amount
$_order_detail_text_5 = __("項目"); // Items
$_order_detail_text_6 = __("會員"); // Member
$_order_detail_text_7 = __("付款方法"); // Payment method

$_tbl_header_1 = __("產品"); // product
$_tbl_header_2 = __("售價"); // price
$_tbl_header_3 = __("數量"); // quantity
$_tbl_header_4 = __("總額"); // total

$content = '';
$out = '';
$header_image = '';
$edit = '';
$oder = '';
$total = 0;
$subtotal = 0;

$order = $pages->get($input->get->id); // get order detail record

if($input->get->id) {

$out .= "<div class='order-detail-container'>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_6}: <strong>".$order->member->name."</p>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_1}: <strong>".$order->order_number."</p>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_2}: <strong>".$order->paypal_transaction_id."</p>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_3}: <strong>".date('d-M-Y', $order->order_time)."</p>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_4}: <strong>".number_format($order->transaction_amount)."</p>";
$out .= "<p class='no-indent'><strong>{$_order_detail_text_7}: <strong>".$order->payment_method."</p>";
$out .= "<h3>$_order_detail_text_5</h3>";
$out .= "<table class='table table-bordered'>";
$out .= "<thead>";
$out .= "<tr>";
$out .= "<th>{$_tbl_header_1}</th>";
$out .= "<th class='center'>{$_tbl_header_2}</th>";
$out .= "<th class='center'>{$_tbl_header_3}</th>";
$out .= "<th class='center'>{$_tbl_header_4}</th>";
$out .= "</thead>";
$out .= "<tbody>";

foreach($order->order_items as $item) {
    $p = $pages->get($item->product_id);
    $out .= "<tr>";
    //$out .= "<td>{$item->product_name}</td>";
    $out .= "<td>{$p->title}</td>";
    $out .= "<td class='center'>{$item->product_price}</td>";
    $out .= "<td class='center'>{$item->product_quantity}</td>";
    $total = $item->product_price * $item->product_quantity;
    $out .= "<td class='center'>".number_format($total)."</td>";
    $out .= "</tr>";
    $subtotal += $total;
}
$out .= "</tbody>";
$out .= "</table>";
$out .= "</div>";

$content .= $out;
} else {
     $session->redirect($homepage->url);
}

Share this post


Link to post
Share on other sites

Hmmm, I don't have much time to test myself for the moment, but in your initial code to create the order, try saving the order before adding the order items:

Add 

$p->save();

before

foreach($session->get("cart_item") as $cart_item) {

Also, I don't see you add a parent to the page during the creation. It might not be necessary, but you can try to see whether this changes anything.

Share this post


Link to post
Share on other sites

Hmmm, I don't have much time to test myself for the moment, but in your initial code to create the order, try saving the order before adding the order items:

Add 

$p->save();

before

foreach($session->get("cart_item") as $cart_item) {

Also, I don't see you add a parent to the page during the creation. It might not be necessary, but you can try to see whether this changes anything.

Tried your suggestion. Worst than before

This time only the default language get a count from order items

Settting a parent did not help.

Share this post


Link to post
Share on other sites

I'll try to replicate this problem on my side , to see whether I can understand it . However, I have a few questions:

- Which version of Processwire are you using ?

- What are the fields types of the fields on the product template

- When you create an order on the English backend, and then view the order in the back-end in English (by setting your profile language to English), do the order items appear?

– Do you have the same problem if you create the order in the chs front-end ? Do the order items then not appear in Chinese simplified, but appear in English and default languages ?

Share this post


Link to post
Share on other sites

product template

post-2272-0-58510000-1461395044_thumb.pn

order_items repeater field

post-2272-0-99325400-1461395067_thumb.pn

post-2272-0-54271400-1461395077_thumb.pn

Which version of Processwire are you using ?

>2.7.3

What are the fields types of the fields on the product template

> See the above screen cap

When you create an order on the English backend, and then view the order in the back-end in English (by setting your profile language to English), do the order items appear?

> No matter which language used in user profile, creating an order in back-end ui directly, All items can shown in all languages.

ps I used admin to create an order. other user role has no permission to created an order thru the back-end.

Do you have the same problem if you create the order in the chs front-end ? Do the order items then not appear in Chinese simplified, but appear in English and default languages ?

> no matter using chs or english front-end language for the whole order purchase, order item shown on default language only.

Share this post


Link to post
Share on other sites

By the way, I did find other people has similar issue on repeater field on multilanguage site

https://processwire.com/talk/topic/11300-problem-with-repeater-fields-in-multi-language-pages/

https://processwire.com/talk/topic/11732-repeater-fields-not-displayed-on-non-default-language-page/?hl=repeater

Unfortunately, they didn't get a solid answer or find out what caused that problem.

Share this post


Link to post
Share on other sites

By the way, I did find other people has similar issue on repeater field on multilanguage site

https://processwire.com/talk/topic/11300-problem-with-repeater-fields-in-multi-language-pages/

https://processwire.com/talk/topic/11732-repeater-fields-not-displayed-on-non-default-language-page/?hl=repeater

Unfortunately, they didn't get a solid answer or find out what caused that problem.

I would suggest that you please open a github issue on this, in addition to commenting on this problem here:

https://github.com/ryancramerdesign/ProcessWire/issues

Thanks

Share this post


Link to post
Share on other sites

If ESRCH could replicate the same issue, then we can ensure there is a bug in between repeater field and multi-language

Share this post


Link to post
Share on other sites

If ESRCH could replicate the same issue, then we can ensure there is a bug in between repeater field and multi-language

You make a good point, however whether it's a bug or not, reporting and tracking in github ensures that your problem gets proper visibility with other important issues.

Share this post


Link to post
Share on other sites

I made a quick attempt at replicating the issue, but it worked for me. I unfortunately don't have the time to work on this further today, so if someone else has an idea how to solve this...

Share this post


Link to post
Share on other sites

Hey guys, I think a few things in the code examples above need to be moved around. Also, since Repeaters don't know about languages, if you are creating repeater items on your own from the PHP side, you'll have to enable those items for all the languages they are applicable to. I replied on that GitHub issue report, along with suggestions for adjustments to the code. 

  • Like 4

Share this post


Link to post
Share on other sites

Thank you Ryan for my code adjustments commented on the github.

The issue is resolved.

I posted the complete code snippet with Ryan's code adjustment

// Add a customer order in database
$orders = $pages->get(1152);
$p = new Page();
$orderByUser = $user;
$p->template = "order";
$p->parent = $orders;
$counter_name = $order_number_prefix . date('Y');
$number = $this->modules->get('DatabaseCounters')->next($counter_name, 1, 5000);
$ordernumber = $counter_name . '-' . sprintf("%06u", $number);
$p->of(false);
$def = $wire->languages->get("default");
$chs = $wire->languages->get("chs");
$eng = $wire->languages->get("eng");
$p->title->setLanguageValue($def, $ordernumber);
$p->title->setLanguageValue($chs, $ordernumber);
$p->title->setLanguageValue($eng, $ordernumber);
$p->order_number = $ordernumber;
$p->member = $orderByUser;
$p->payment_method = $session->get("payment_method");
$p->order_time = $session->get("order_time");
$p->paypal_transaction_id = $session->get("paypal_transaction_id");

foreach($languages as $lang)
    $p->set("status$lang", 1);
$p->save();

foreach($session->get("cart_item") as $cart_item) {
    $item = $p->items->getNew();
    foreach($languages as $lang)
        $item->set("status$lang", 1);
    $item->product_id = $cart_item['id'];
    $item->product_price = $cart_item['price'];
    $item->product_quantity = $cart_item['quantity'];
    $item->save();
    $p->items->add($item);
    $transaction_amount += ($cart_item['price'] * $cart_item['quantity']);
}

$p->transaction_amount = $transaction_amount;
$p->save();

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Juergen
      Hello @ all,
      I have created an inputfield with a configuration field in the backend where you can set a time format for every language (see screenshot below).

      As you can see both language values (default and German) have the default value(%R), but I have set different values, which were correctly stored in the DB (see screenshot below):

      As you can see the values are '%R' and '%r'.
      I have created the configuration inputfield like this:
      /** @var InputfieldText $f */ $languages = $this->wire('languages'); $f = $this->wire('modules')->get('InputfieldText'); $f->attr('name+id', 'timeformat'); $f->label = $this->_('Timeformat on frontend'); $f->initValue = '%R';//default value $f->attr('value', $this->timeformat ? $this->timeformat : '%R'); $this->message($this->get('timesformat')); if($languages) { $f->useLanguages = true; foreach($languages as $language) { if($language->isDefault()) continue; $f->set("value$language", (string) $this->get("timeformat$language->id")); } } $f->inputType = 'text'; $f->description = $this->_('Please enter the time format that the times should appear on the frontend in strftime format.'); $f->notes = sprintf($this->_('For example shows the time as 08:00, as 08:00 AM. You can find more examples at %s.'), '<a href="https://www.php.net/manual/de/function.strftime.php">https://www.php.net/manual/de/function.strftime.php</a>'); $f->columnWidth = 100; The important part here is:
      if($languages) { $f->useLanguages = true; foreach($languages as $language) { if($language->isDefault()) continue; $f->set("value$language", (string) $this->get("timeformat$language->id")); } } I have borrowed the code from the DateTimeInputfield (https://github.com/processwire/processwire/blob/master/wire/modules/Inputfield/InputfieldDatetime/InputfieldDatetime.module), but the field values will be always populated with the default value ('%R').
      Are I am missing something? Does anyone has experience with multilanguage fields and could help me out?
      Thanks in advance.
    • By marcus
      wireshell 1.0.0 is out    
      See Bea's post
       


      -------- Original post -----------
        Now this one could be a rather long post about only an experimental niche tool, but maybe a helpful one for some, so stay with me   Intention Do you guys know "Artisan" (Laravel) or "Drush" (Drupal)? If not: These are command line companions for said systems, and very useful for running certain (e.g. maintenance, installation) task quickly - without having to use the Admin Interface, first and foremost when dealing with local ProcessWire installations. And since it has a powerful API and an easy way of being bootstrapped into CLIs like this, I think such a tool has a certain potential in the PW universe.    It's totally not the first approach of this kind. But: this one should be easily extendable - and is based on PHP (specifically: the Console component of the Symfony Framework). Every command is tidily wrapped in its own class, dependencies are clearly visible, and so on.   ( Here was the outdated documentation. Please visit wireshell.pw for the current one )
    • By snobjorn
      Here's my Norwegian language pack for ProcessWire. I've been adding translations over some time, to suit my own projects users needs.
      Last updated:
      2020/06/29 (June 29, 2020)
      Status:
      Not yet complete. Translations that non-superusers will see is prioritized.
      Name:
      ProcessWire-Norwegian-Language-Pack-nb-NO
      Translated using:
      ProcessWire 3.0.161 dev
      Number of files:
      202 wire files and 97 site files – ranging from just started to completely translated. The site files includes translation some free and some pro modules, see the complete list in the README.md at GitHub.
      Available at GitHub:
      https://github.com/snobjorn/processwire-norwegian-language-pack-nb-no
    • By Sten
      Hello
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By Robin S
      This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure.
      I'm not using this module anywhere myself but maybe it's useful to somebody.
      Repeater Depth Helper
      This module does two things relating to Repeater fields that have the "Item depth" option enabled:
      It enforces some depth rules for Repeater fields on save. Those rules are:
      The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value.
      Helper method
      The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children.
      Example

      The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list.
      // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items);
       
      https://github.com/Toutouwai/RepeaterDepthHelper
      https://modules.processwire.com/modules/repeater-depth-helper/
×
×
  • Create New...