Transfluent - Version 1.4.0

Version Notes

Added translation support for CMS content

Download this release

Release Info

Developer Transfluent Ltd
Extension Transfluent
Version 1.4.0
Comparing to
See all releases


Code changes from version 1.3.2 to 1.4.0

app/code/community/Transfluent/Translate/Model/Base/Backendclient.php CHANGED
@@ -146,7 +146,7 @@ class Transfluent_Translate_Model_Base_Backendclient extends Mage_Adminhtml_Cont
146
  $message['message'] = 'You have successfully connected to Transfluent.com';
147
  $session = Mage::getSingleton('core/session');
148
  /** @var Mage_Core_Model_Session $session */
149
- $session->addSuccess('You have successfully authenticated. If you have not yet activated billing mode for your account, you should do it next by contacting <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> in order to setup invoicing. Or visit <a href="https://www.transfluent.com/my-account/">your Transfluent account page</a> to setup a credit card charging.');
150
  }
151
  return $message;
152
  }
@@ -184,6 +184,10 @@ class Transfluent_Translate_Model_Base_Backendclient extends Mage_Adminhtml_Cont
184
  return $this->CallApi('magento/quote', self::HTTP_POST, $payload);
185
  }
186
 
 
 
 
 
187
  public function OrderCategoryQuote($quote_id, $instructions) {
188
  $payload = array(
189
  'id' => $quote_id,
@@ -196,14 +200,40 @@ class Transfluent_Translate_Model_Base_Backendclient extends Mage_Adminhtml_Cont
196
  return $this->CallApi('magento/quote', self::HTTP_POST, $payload);
197
  }
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  public function CreateCategoryQuote($source_store, $source_language, $target_store, $target_language, $level, $collision_strategy, $category_ids, $translate_fields = null) {
200
  $extension_callback_endpoint = Mage::getUrl('transfluenttranslate/');
201
  $store_endpoint = Mage::app()->getStore($target_store)->getUrl('transfluenttranslate/'); // returns URL with ?___store=[STORE_CODE]
202
  $version = Mage::getVersion();
 
203
  $payload = array(
204
  'magento_ver' => $version,
205
  'magento_url' => $extension_callback_endpoint,
206
  'magento_store_url' => $store_endpoint,
 
207
  'source_store' => $source_store,
208
  'source_language' => $source_language,
209
  'target_store' => $target_store,
@@ -229,7 +259,7 @@ class Transfluent_Translate_Model_Base_Backendclient extends Mage_Adminhtml_Cont
229
  $this->SaveConfiguration($email, $res['response']['token']);
230
  $session = Mage::getSingleton('core/session');
231
  /** @var Mage_Core_Model_Session $session */
232
- $session->addSuccess('You have successfully created a new account. We have sent your password to your email. Next you should contact <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> in order to setup invoicing.');
233
  }
234
  return $res;
235
  }
146
  $message['message'] = 'You have successfully connected to Transfluent.com';
147
  $session = Mage::getSingleton('core/session');
148
  /** @var Mage_Core_Model_Session $session */
149
+ $session->addSuccess('You have successfully authenticated. If you have not yet activated billing mode for your account, you should do it next by contacting <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> in order to setup invoicing or visit <a href="https://www.transfluent.com/my-account/#/creditcard" target="_blank">your Transfluent account page</a> to setup credit card payments.');
150
  }
151
  return $message;
152
  }
184
  return $this->CallApi('magento/quote', self::HTTP_POST, $payload);
185
  }
186
 
187
+ public function OrderCmsQuote($quote_id, $instructions) {
188
+ return $this->OrderCategoryQuote($quote_id, $instructions);
189
+ }
190
+
191
  public function OrderCategoryQuote($quote_id, $instructions) {
192
  $payload = array(
193
  'id' => $quote_id,
200
  return $this->CallApi('magento/quote', self::HTTP_POST, $payload);
201
  }
202
 
203
+ public function CreateCmsContentQuote($source_store, $source_language, $target_store, $target_language, $level, $collision_strategy, $cms_page_ids, $cms_block_ids) {
204
+ $extension_callback_endpoint = Mage::getUrl('transfluenttranslate/');
205
+ $store_endpoint = Mage::app()->getStore($target_store)->getUrl('transfluenttranslate/'); // returns URL with ?___store=[STORE_CODE]
206
+ $version = Mage::getVersion();
207
+ $extension_version = Mage::getConfig()->getNode()->modules->Transfluent_Translate->version->__toString();
208
+ $payload = array(
209
+ 'magento_ver' => $version,
210
+ 'magento_url' => $extension_callback_endpoint,
211
+ 'magento_store_url' => $store_endpoint,
212
+ 'extension_ver' => $extension_version,
213
+ 'source_store' => $source_store,
214
+ 'source_language' => $source_language,
215
+ 'target_store' => $target_store,
216
+ 'target_language' => $target_language,
217
+ 'level' => $level,
218
+ 'collision' => $collision_strategy,
219
+ 'cms_page_ids' => '[' . $cms_page_ids . ']',
220
+ 'cms_block_ids' => '[' . $cms_block_ids . ']',
221
+ 'token' => $this->token,
222
+ 'hash' => md5($this->token)
223
+ );
224
+ return $this->CallApi('magento/quote', self::HTTP_POST, $payload);
225
+ }
226
+
227
  public function CreateCategoryQuote($source_store, $source_language, $target_store, $target_language, $level, $collision_strategy, $category_ids, $translate_fields = null) {
228
  $extension_callback_endpoint = Mage::getUrl('transfluenttranslate/');
229
  $store_endpoint = Mage::app()->getStore($target_store)->getUrl('transfluenttranslate/'); // returns URL with ?___store=[STORE_CODE]
230
  $version = Mage::getVersion();
231
+ $extension_version = Mage::getConfig()->getNode()->modules->Transfluent_Translate->version->__toString();
232
  $payload = array(
233
  'magento_ver' => $version,
234
  'magento_url' => $extension_callback_endpoint,
235
  'magento_store_url' => $store_endpoint,
236
+ 'extension_ver' => $extension_version,
237
  'source_store' => $source_store,
238
  'source_language' => $source_language,
239
  'target_store' => $target_store,
259
  $this->SaveConfiguration($email, $res['response']['token']);
260
  $session = Mage::getSingleton('core/session');
261
  /** @var Mage_Core_Model_Session $session */
262
+ $session->addSuccess('You have successfully created a new account. We have sent your password to your email. Next you should contact <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> in order to setup invoicing or visit <a href="https://www.transfluent.com/my-account/#/creditcard" target="_blank">your Transfluent account page</a> to setup credit card payments.');
263
  }
264
  return $res;
265
  }
app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluentorderController.php CHANGED
@@ -4,6 +4,15 @@
4
  * Class Transfluent_Translate_Adminhtml_TransfluentorderController
5
  */
6
  class Transfluent_Translate_Adminhtml_TransfluentorderController extends Mage_Adminhtml_Controller_Action {
 
 
 
 
 
 
 
 
 
7
  protected function _initAction() {
8
  $this->loadLayout()
9
  ->getLayout()
@@ -436,6 +445,160 @@ class Transfluent_Translate_Adminhtml_TransfluentorderController extends Mage_Ad
436
  $this->renderLayout();
437
  }
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  public function orderByCategoryStep1Action($init_layout = true) {
440
  if ($init_layout) {
441
  $this->_initAction();
4
  * Class Transfluent_Translate_Adminhtml_TransfluentorderController
5
  */
6
  class Transfluent_Translate_Adminhtml_TransfluentorderController extends Mage_Adminhtml_Controller_Action {
7
+ protected $_publicActions = array('redirectToQuote');
8
+
9
+ public function redirectToQuoteAction() {
10
+ $quote_id = $this->getRequest()->getParam('quote_id');
11
+ $source_store_id = $this->getRequest()->getParam('source_store');
12
+ $target_store_id = $this->getRequest()->getParam('target_store');
13
+ Mage::app()->getResponse()->setRedirect(Mage::helper("adminhtml")->getUrl("transfluent/adminhtml_transfluentorder/orderFromCmsStep3", array("quote_id" => $quote_id, "source" => $source_store_id, "target" => $target_store_id)));
14
+ }
15
+
16
  protected function _initAction() {
17
  $this->loadLayout()
18
  ->getLayout()
445
  $this->renderLayout();
446
  }
447
 
448
+ public function orderFromCmsStep5Action() {
449
+ $this->_initAction();
450
+
451
+ /** @var Transfluent_Translate_Model_Base_Backendclient $translate */
452
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
453
+ $quote_id = $this->getRequest()->getParam('quote_id');
454
+ $source = $this->getRequest()->getParam('source');
455
+ $instructions = $this->getRequest()->getParam('instructions');
456
+ $instructions .= PHP_EOL . PHP_EOL . 'Text is from webstore: ' . Mage::app()->getStore($source)->getBaseUrl() . PHP_EOL . PHP_EOL;
457
+
458
+ $data = $translate->OrderCmsQuote($quote_id, $instructions);
459
+ if (!$data || $data['status'] != 'OK') {
460
+ $this->getLayout()->getMessagesBlock()->addError('Failed to place the order. Error: ' . @$data['error']['message']);
461
+ $this->orderFromCmsStep3Action(false);
462
+ return;
463
+ }
464
+
465
+ $this->_addContent(
466
+ $this
467
+ ->getLayout()
468
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder')
469
+ ->setTemplate('transfluent/order/cms_step5.phtml')->setData('fork_id', $data['response'])->setData('quote_id', $quote_id)
470
+ );
471
+ $this->renderLayout();
472
+ }
473
+
474
+ public function orderFromCmsStep3Action($init_layout = true) {
475
+ /** @var Transfluent_Translate_Model_Base_Backendclient $translate */
476
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
477
+ $quote_id = $this->getRequest()->getParam('quote_id');
478
+ $target = $this->getRequest()->getParam('target');
479
+ $source = $this->getRequest()->getParam('source');
480
+ $cookie = Mage::getSingleton('core/cookie');
481
+ /** @var Mage_Core_Model_Cookie $cookie */
482
+
483
+ if ($quote_id && $this->getRequest()->getParam('isAjax')) {
484
+ $data = $translate->GetCategoryQuote($quote_id);
485
+ $this->getResponse()
486
+ ->setBody(
487
+ Mage::helper('core')->jsonEncode($data['response']))
488
+ ->setHttpResponseCode(200)
489
+ ->setHeader('Content-type', 'application/json', true);
490
+ return;
491
+ } else if ($cookie->get('_tf_restore_quote')) {
492
+ $cookie->delete('_tf_restore_quote', '/');
493
+ $quote_data = unserialize($cookie->get('_tf_restore_quote'));
494
+ $quote_id = $quote_data['quote_id'];
495
+ $target = (int)$quote_data['target'];
496
+ $source = (int)$quote_data['source'];
497
+ }
498
+
499
+ if ($init_layout) {
500
+ // Preserve any pre-generated errors
501
+ $this->_initAction();
502
+ }
503
+
504
+ $translate_blocks = $this->getRequest()->getParam('translate_blocks');
505
+ $translate_pages = $this->getRequest()->getParam('translate_pages');
506
+ $all_cms_page_ids = $this->getRequest()->getParam('cms_page_ids') ?: array();
507
+ $all_cms_block_ids = $this->getRequest()->getParam('cms_block_ids') ?: array();
508
+
509
+ if (!$quote_id && (!$translate_blocks || !$translate_pages)) {
510
+ if (empty($all_cms_page_ids) && empty($all_cms_block_ids)) {
511
+ $this->orderFromCmsStep2Action(false);
512
+ return;
513
+ }
514
+ }
515
+
516
+ $cms_page_model = Mage::getModel('cms/page');
517
+ if ($translate_pages) {
518
+ $all_cms_page_ids = $cms_page_model->getCollection()->getAllIds();
519
+ }
520
+ $cms_page_ids_str = implode(",", $all_cms_page_ids);
521
+
522
+ $cms_block_model = Mage::getModel('cms/block');
523
+ if ($translate_blocks) {
524
+ $all_cms_block_ids = $cms_block_model->getCollection()->getAllIds();
525
+ }
526
+ $cms_block_ids_str = implode(",", $all_cms_block_ids);
527
+
528
+ $source_store = Mage::app()->getStore($source);
529
+ $target_store = Mage::app()->getStore($target);
530
+ $level = $this->getRequest()->getParam('level');
531
+ $collision_strategy = $this->getRequest()->getParam('collision');
532
+
533
+ if (!$quote_id) {
534
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
535
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
536
+ $source_store_locale_code = $languageHelper->GetStoreLocale($source_store->getCode());
537
+ $target_store_locale_code = $languageHelper->GetStoreLocale($target_store->getCode());
538
+ $data = $translate->CreateCmsContentQuote($source, $source_store_locale_code, $target, $target_store_locale_code, $level, $collision_strategy, $cms_page_ids_str, $cms_block_ids_str);
539
+ }
540
+
541
+ $block = $this->getLayout()->createBlock('transfluenttranslate/adminhtml_transfluentorder')->setTemplate('transfluent/order/cms_step3.phtml');
542
+
543
+ if (!$quote_id && $data['status'] == 'ERROR') {
544
+ $block->setData('quote_id', null);
545
+ $this->getLayout()->getMessagesBlock()->addError($data['error']['message']);
546
+ } else if (!$quote_id) {
547
+ $quote_id = $data['response'];
548
+ $block->setData('quote_id', $quote_id);
549
+ } else {
550
+ $block->setData('quote_id', $quote_id);
551
+ }
552
+
553
+ $this->_addContent($block);
554
+ $this->renderLayout();
555
+ }
556
+
557
+ public function orderFromCmsStep2Action($init_layout = true) {
558
+ if ($init_layout) {
559
+ $this->_initAction();
560
+ }
561
+
562
+ $target = $this->getRequest()->getParam('target');
563
+ if (!$target) {
564
+ $this->getLayout()->getMessagesBlock()->addError('Please select a target language&store for translations!');
565
+ $this->orderByCategoryStep1Action(false);
566
+ return;
567
+ }
568
+ $source = $this->getRequest()->getParam('source');
569
+ if ($source == $target) {
570
+ $this->getLayout()->getMessagesBlock()->addError('You can not translate into the source store as each store may have only one locale. You need a pair of stores in different languages, please refer our getting started guide for Magento to do that.');
571
+ $this->orderByCategoryStep1Action(false);
572
+ return;
573
+ }
574
+
575
+ $this->_addContent(
576
+ $this
577
+ ->getLayout()
578
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder')
579
+ ->setTemplate('transfluent/order/cms_step2.phtml')
580
+ );
581
+ $this->renderLayout();
582
+ }
583
+
584
+ public function orderFromCmsStep1Action($init_layout = true) {
585
+ if ($init_layout) {
586
+ $this->_initAction();
587
+ }
588
+
589
+ if (!Mage::getStoreConfig('transfluenttranslate/account/token')) {
590
+ $login_url = Mage::helper("adminhtml")->getUrl("adminhtml/system_config/edit", array('section' => 'transfluenttranslate'));
591
+ $this->getLayout()->getMessagesBlock()->addError('Please login or create an account <a href="' . $login_url . '">first</a>!');
592
+ }
593
+ $this->_addContent(
594
+ $this
595
+ ->getLayout()
596
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder')
597
+ ->setTemplate('transfluent/order/cms_step1.phtml')
598
+ );
599
+ $this->renderLayout();
600
+ }
601
+
602
  public function orderByCategoryStep1Action($init_layout = true) {
603
  if ($init_layout) {
604
  $this->_initAction();
app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluenttranslateController.php CHANGED
@@ -40,6 +40,7 @@ class Transfluent_Translate_Adminhtml_TransfluenttranslateController extends Mag
40
  $this
41
  ->getLayout()
42
  ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate')
 
43
  );
44
  $this->renderLayout();
45
  }
40
  $this
41
  ->getLayout()
42
  ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate')
43
+ ->setTemplate('transfluent/order/listing.phtml')
44
  );
45
  $this->renderLayout();
46
  }
app/code/community/Transfluent/Translate/controllers/TranslationController.php CHANGED
@@ -11,6 +11,8 @@ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_F
11
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-title/" => '_saveCategoryMetaTitle',
12
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-keywords/" => '_saveCategoryMetaKeywords',
13
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-description/" => '_saveCategoryMetaDescription',
 
 
14
  );
15
 
16
  private function serveRequest($payload) {
@@ -59,6 +61,164 @@ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_F
59
  $this->serveRequest($response);
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  public function getProductDetailsAction() {
63
  try {
64
  $this->_validateToken();
@@ -70,13 +230,18 @@ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_F
70
  $target_store_id = $this->getRequest()->getParam('target_store');
71
  $source_store_id = $this->getRequest()->getParam('source_store');
72
  $product_model = Mage::getModel('catalog/product');
73
- /** @var Mage_Catalog_Model_Product $model */
 
 
74
 
75
  $available_fields = array();
76
  $products_out = array();
77
  foreach ($product_ids AS $product_id) {
78
  $product = $product_model->setStoreId($target_store_id)->load($product_id);
79
- if (!$product) {
 
 
 
80
  continue;
81
  }
82
  /** @var Mage_Catalog_Model_Product $product */
@@ -92,13 +257,14 @@ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_F
92
  continue;
93
  } else if ($collision == 'overwrite') {
94
  // Delete: Overwrite store specific values with new translations
95
- $master_product = $product_model->setStoreId($source_store_id)->load($product_id);
96
  $product_data[$product_field] = $master_product->getData($product_field);
97
  continue;
98
  }
99
  }
100
  $product_data[$product_field] = $product->getData($product_field);
101
  }
 
 
102
  $products_out[] = $product_data;
103
  }
104
 
@@ -442,6 +608,194 @@ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_F
442
  return $this->_updateOrder($store_id, $text_id, $payload['level']);
443
  }
444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  private function _saveProductDetails($matches, $payload, $text_id) {
446
  $store_id = $matches[1];
447
  $product_id = $matches[2];
11
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-title/" => '_saveCategoryMetaTitle',
12
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-keywords/" => '_saveCategoryMetaKeywords',
13
  "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-description/" => '_saveCategoryMetaDescription',
14
+ "/store\-([0-9]{1,})\-([0-9]{1,})\-cms\-page\-([0-9]{1,})\-(.*)/" => '_saveCmsPageDetails',
15
+ "/store\-([0-9]{1,})\-([0-9]{1,})\-cms\-block\-([0-9]{1,})\-(.*)/" => '_saveCmsBlockDetails',
16
  );
17
 
18
  private function serveRequest($payload) {
61
  $this->serveRequest($response);
62
  }
63
 
64
+ public function preDispatch() {
65
+ if ($this->getRequest()->getActionName() == 'returnToQuote') {
66
+ // Make sure admin session gets initialized before normal dispatch routine, otherwise admin is always logged out
67
+ Mage::getSingleton('core/session', array('name'=>'adminhtml'));
68
+ }
69
+ parent::preDispatch();
70
+ }
71
+
72
+ public function returnToQuoteAction() {
73
+ $source_store_id = $this->getRequest()->getParam('source_store');
74
+ $target_store_id = $this->getRequest()->getParam('target_store');
75
+ $quote_id = $this->getRequest()->getParam('quote_id');
76
+
77
+ $mage_admin_url = Mage::getModel('adminhtml/url');
78
+ /** @var Mage_Adminhtml_Model_Url $mage_admin_url */
79
+ $mage_admin_url->setStore(0);
80
+
81
+ $admin_html_helper = Mage::helper('adminhtml');
82
+ /** @var Mage_Adminhtml_Helper_Data $admin_html_helper */
83
+
84
+ if ($admin_html_helper->getCurrentUserId()) {
85
+ // LOGGED-IN: REDIRECT TO: BASE + transfluent/adminhtml_transfluentorder/redirectToQuote/quote_id/HkvrSz7z/source_store/1/target_store/4/
86
+ $quote_order_step3_url = $mage_admin_url->getUrl('transfluent/adminhtml_transfluentorder/redirectToQuote', array('source_store' => $source_store_id, 'target_store' => $target_store_id, 'quote_id' => $quote_id));
87
+ $this->getResponse()->setRedirect($quote_order_step3_url);
88
+ return;
89
+ }
90
+ // NOT LOGGED IN: SAVE QUOTE DETAILS INTO A COOKIE AND THEN REDIRECT TO PLAIN STEP URL (LOGIN CLEARS ANY REQUEST OR ROUTE PARAMETERS)
91
+ $cookie = Mage::getSingleton('core/cookie');
92
+ /** @var Mage_Core_Model_Cookie $cookie */
93
+ $cookie->set('_tf_restore_quote', serialize(array('source' => $source_store_id, 'target' => $target_store_id, 'quote_id' => $quote_id)), null, '/');
94
+ $quote_order_step3_url = $mage_admin_url->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep3');
95
+ $this->getResponse()->setRedirect($quote_order_step3_url);
96
+ }
97
+
98
+ public function getCmsPageAction() {
99
+ try {
100
+ $this->_validateToken();
101
+ $page_id = $this->getRequest()->getParam('page_id');
102
+ $collision = $this->getRequest()->getParam('collision');
103
+
104
+ $target_store_id = $this->getRequest()->getParam('target_store');
105
+ $source_store_id = $this->getRequest()->getParam('source_store');
106
+ $cms_page_model = Mage::getModel('cms/page');
107
+ /** @var Mage_Cms_Model_Page $cms_page_model */
108
+ $page = $cms_page_model->setStoreId($source_store_id)->load($page_id);
109
+ /** @var Mage_Cms_Model_Page $page */
110
+ if ($page->isEmpty() || $page->isObjectNew()) {
111
+ throw new Exception('PAGE_NOT_ASSOCIATED_WITH_STORE');
112
+ }
113
+
114
+ if ($collision != 'overwrite') {
115
+ $cms_page_collection = $cms_page_model->getCollection();
116
+ /** @var Mage_Cms_Model_Resource_Page_Collection $cms_page_collection */
117
+ $cms_page_collection->addFilter('identifier', $page->getIdentifier());
118
+ if ($cms_page_collection->count() != 1) {
119
+ $tmp_cms_page_model = Mage::getModel('cms/page');
120
+ /** @var Mage_Cms_Model_Page $cms_page_model */
121
+ foreach ($cms_page_collection AS $tmp_page) {
122
+ /** @var Mage_Cms_Model_Page $tmp_page */
123
+ $tmp_page = $tmp_cms_page_model->setStoreId($target_store_id)->load($tmp_page->getId());
124
+ if ($tmp_page->isObjectNew() || $tmp_page->isEmpty() || $tmp_page->getId() == $page->getId()) {
125
+ continue;
126
+ }
127
+ switch ($collision) {
128
+ case 'source':
129
+ // Use page in target store as source for translation
130
+ // ..page is bound to target store view, use as source!
131
+ $page = $tmp_page;
132
+ break 2;
133
+ default:
134
+ case 'translated':
135
+ // Assume page is already translated [if it has been bound to target store view]
136
+ throw new Exception('PAGE_ALREADY_TRANSLATED');
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ $page_url = Mage::app()->getStore($source_store_id)->getUrl($page->getIdentifier());
143
+ $response = array(
144
+ 'id' => $page_id,
145
+ 'source_id' => $page->getId(),
146
+ 'is_active' => $page->getIsActive(),
147
+ 'title' => $page->getTitle(),
148
+ 'meta' => array(
149
+ 'keywords' => $page->getMetaKeywords(),
150
+ 'description' => $page->getMetaDescription(),
151
+ ),
152
+ 'identifier' => $page->getIdentifier(),
153
+ 'url' => $page_url,
154
+ 'content' => $page->getContent(),
155
+ 'store_id' => $page->store_id
156
+ );
157
+ } catch (Exception $e) {
158
+ $response = $e;
159
+ }
160
+ $this->serveRequest($response);
161
+ }
162
+
163
+ public function getCmsBlockAction() {
164
+ try {
165
+ $this->_validateToken();
166
+ $block_id = $this->getRequest()->getParam('block_id');
167
+ $collision = $this->getRequest()->getParam('collision');
168
+
169
+ $target_store_id = $this->getRequest()->getParam('target_store');
170
+ $source_store_id = $this->getRequest()->getParam('source_store');
171
+ $cms_block_model = Mage::getModel('cms/block');
172
+ /** @var Mage_Cms_Model_Block $cms_block_model */
173
+ $block = $cms_block_model->setStoreId($source_store_id)->load($block_id);
174
+ /** @var Mage_Cms_Model_Block $block */
175
+ if ($block->isEmpty() || $block->isObjectNew()) {
176
+ throw new Exception('BLOCK_NOT_ASSOCIATED_WITH_STORE');
177
+ }
178
+
179
+ if ($collision != 'overwrite') {
180
+ $cms_block_collection = $cms_block_model->getCollection();
181
+ /** @var Mage_Cms_Model_Resource_Block_Collection $cms_block_collection */
182
+ $cms_block_collection->addFilter('identifier', $block->getIdentifier());
183
+ if ($cms_block_collection->count() != 1) {
184
+ $tmp_cms_block_model = Mage::getModel('cms/block');
185
+ /** @var Mage_Cms_Model_Block $cms_block_model */
186
+ foreach ($cms_block_collection AS $tmp_block) {
187
+ /** @var Mage_Cms_Model_Block $tmp_block */
188
+ $tmp_block = $tmp_cms_block_model->setStoreId($target_store_id)->load($tmp_block->getId());
189
+ if ($tmp_block->isObjectNew() || $tmp_block->isEmpty() || $tmp_block->getId() == $block->getId()) {
190
+ continue;
191
+ }
192
+ switch ($collision) {
193
+ case 'source':
194
+ // Use block in target store as source for translation
195
+ // ..block is bound to target store view, use as source!
196
+ $block = $tmp_block;
197
+ break 2;
198
+ default:
199
+ case 'translated':
200
+ // Assume block is already translated [if it has been bound to target store view]
201
+ throw new Exception('BLOCK_ALREADY_TRANSLATED');
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ $response = array(
208
+ 'id' => $block_id,
209
+ 'source_id' => $block->getId(),
210
+ 'is_active' => $block->getIsActive(),
211
+ 'title' => $block->getTitle(),
212
+ 'identifier' => $block->getIdentifier(),
213
+ 'content' => $block->getContent(),
214
+ 'store_id' => $block->store_id
215
+ );
216
+ } catch (Exception $e) {
217
+ $response = $e;
218
+ }
219
+ $this->serveRequest($response);
220
+ }
221
+
222
  public function getProductDetailsAction() {
223
  try {
224
  $this->_validateToken();
230
  $target_store_id = $this->getRequest()->getParam('target_store');
231
  $source_store_id = $this->getRequest()->getParam('source_store');
232
  $product_model = Mage::getModel('catalog/product');
233
+ /** @var Mage_Catalog_Model_Product $product_model */
234
+ $master_product = Mage::getModel('catalog/product');
235
+ /** @var Mage_Catalog_Model_Product $product_model */
236
 
237
  $available_fields = array();
238
  $products_out = array();
239
  foreach ($product_ids AS $product_id) {
240
  $product = $product_model->setStoreId($target_store_id)->load($product_id);
241
+ /** @var Mage_Catalog_Model_Product $product */
242
+ $master_product = $master_product->setStoreId($source_store_id)->load($product_id);
243
+ /** @var Mage_Catalog_Model_Product $master_product */
244
+ if (!$product) { // should be $product->isObjectNew() || $product->isEmpty() ?
245
  continue;
246
  }
247
  /** @var Mage_Catalog_Model_Product $product */
257
  continue;
258
  } else if ($collision == 'overwrite') {
259
  // Delete: Overwrite store specific values with new translations
 
260
  $product_data[$product_field] = $master_product->getData($product_field);
261
  continue;
262
  }
263
  }
264
  $product_data[$product_field] = $product->getData($product_field);
265
  }
266
+ $product_data['exists'] = !$master_product->isObjectNew();
267
+ $product_data['url'] = $master_product->getUrlInStore();
268
  $products_out[] = $product_data;
269
  }
270
 
608
  return $this->_updateOrder($store_id, $text_id, $payload['level']);
609
  }
610
 
611
+ private function _saveCmsBlockDetails($matches, $payload, $text_id) {
612
+ $source_store_id = $matches[1];
613
+ $target_store_id = $matches[2];
614
+ $cms_block_id = $matches[3];
615
+ $field_name = $matches[4];
616
+
617
+ $cms_block_model = Mage::getModel('cms/block');
618
+ /** @var Mage_Cms_Model_Block $cms_block_model */
619
+ $block = $cms_block_model->setStoreId($source_store_id)->load($cms_block_id);
620
+ /** @var Mage_Cms_Model_Block $block */
621
+ if ($block->isEmpty() || $block->isObjectNew()) {
622
+ throw new Exception('SOURCE_BLOCK_NOT_FOUND');
623
+ }
624
+ $new_store_ids = null;
625
+ if (in_array("0", $block->store_id)) {
626
+ // Block visibility is "0", i.e. all stores
627
+ $all_store_ids = array();
628
+ $websites = Mage::app()->getWebsites();
629
+ foreach ($websites AS $website) {
630
+ /** @var Mage_Core_Model_Website $website */
631
+ $stores = $website->getStores();
632
+ foreach ($stores AS $store) {
633
+ /** @var Mage_Core_Model_Store $store */
634
+ if ($store->getId() == $target_store_id) {
635
+ continue;
636
+ }
637
+ $all_store_ids[] = $store->getId();
638
+ }
639
+ }
640
+ $new_store_ids = $all_store_ids;
641
+ } else if (in_array((string)$target_store_id, $block->store_id)) {
642
+ $new_store_ids = array_filter(array_filter($block->store_id, function($value) use ($target_store_id) {
643
+ if ($value == $target_store_id) {
644
+ return null;
645
+ }
646
+ return $value;
647
+ }));
648
+ }
649
+ if ($new_store_ids) {
650
+ $model_data = $block->getData();
651
+ $model_data['stores'] = $new_store_ids;
652
+ $block->setData($model_data);
653
+ try {
654
+ $block->save();
655
+ } catch (Exception $e) {
656
+ throw $e;
657
+ }
658
+ }
659
+
660
+ $cms_block_collection = $cms_block_model->getCollection();
661
+ /** @var Mage_Cms_Model_Resource_Block_Collection $cms_block_collection */
662
+ $cms_block_collection->addFilter('identifier', $block->getIdentifier())->addStoreFilter($target_store_id);
663
+ if ($cms_block_collection->count() == 0) {
664
+ $translated_block = Mage::getModel('cms/block');
665
+ $model_data = $block->getData();
666
+ unset($model_data['block_id']);
667
+ $model_data['stores'] = array($target_store_id);
668
+ } else {
669
+ $translated_block = $cms_block_collection->fetchItem();
670
+ if ($translated_block->getId() == $block->getId()) {
671
+ $translated_block = Mage::getModel('cms/block');
672
+ $model_data = $block->getData();
673
+ unset($model_data['block_id']);
674
+ $model_data['stores'] = array($target_store_id);
675
+ } else {
676
+ // Updating an existing item
677
+ $model_data = $translated_block->getData();
678
+ if (!isset($model_data['stores']) || empty($model_data['stores'])) {
679
+ $model_data['stores'] = array($target_store_id);
680
+ }
681
+ }
682
+ }
683
+ /** @var Mage_Cms_Model_Block $translated_block */
684
+ $translated_block->setData($model_data);
685
+ switch ($field_name) {
686
+ case 'content':
687
+ $translated_block->setContent(($payload['text'] ? $payload['text'] : ''));
688
+ break;
689
+ case 'title':
690
+ $translated_block->setTitle(($payload['text'] ? $payload['text'] : ''));
691
+ break;
692
+ }
693
+ try {
694
+ $translated_block->save();
695
+ } catch (Exception $e) {
696
+ throw $e;
697
+ }
698
+
699
+ return true;
700
+ }
701
+
702
+ private function _saveCmsPageDetails($matches, $payload, $text_id) {
703
+ $source_store_id = $matches[1];
704
+ $target_store_id = $matches[2];
705
+ $cms_page_id = $matches[3];
706
+ $field_name = $matches[4];
707
+
708
+ $cms_page_model = Mage::getModel('cms/page');
709
+ /** @var Mage_Cms_Model_Page $cms_page_model */
710
+ $page = $cms_page_model->setStoreId($source_store_id)->load($cms_page_id);
711
+ /** @var Mage_Cms_Model_Page $page */
712
+ if ($page->isEmpty() || $page->isObjectNew()) {
713
+ throw new Exception('SOURCE_PAGE_NOT_FOUND');
714
+ }
715
+ $new_store_ids = null;
716
+ if (in_array("0", $page->store_id)) {
717
+ // Block visibility is "0", i.e. all stores
718
+ $all_store_ids = array();
719
+ $websites = Mage::app()->getWebsites();
720
+ foreach ($websites AS $website) {
721
+ /** @var Mage_Core_Model_Website $website */
722
+ $stores = $website->getStores();
723
+ foreach ($stores AS $store) {
724
+ /** @var Mage_Core_Model_Store $store */
725
+ if ($store->getId() == $target_store_id) {
726
+ continue;
727
+ }
728
+ $all_store_ids[] = $store->getId();
729
+ }
730
+ }
731
+ $new_store_ids = $all_store_ids;
732
+ } else if (in_array((string)$target_store_id, $page->store_id)) {
733
+ $new_store_ids = array_filter(array_filter($page->store_id, function($value) use ($target_store_id) {
734
+ if ($value == $target_store_id) {
735
+ return null;
736
+ }
737
+ return $value;
738
+ }));
739
+ }
740
+ if ($new_store_ids) {
741
+ $model_data = $page->getData();
742
+ $model_data['stores'] = $new_store_ids; // Page model uses store_id somewhere else, check if this is right.. @todo FIXME
743
+ $page->setData($model_data);
744
+ try {
745
+ $page->save();
746
+ } catch (Exception $e) {
747
+ throw $e;
748
+ }
749
+ }
750
+
751
+ $cms_page_collection = $cms_page_model->getCollection();
752
+ /** @var Mage_Cms_Model_Resource_Page_Collection $cms_page_collection */
753
+ $cms_page_collection->addFilter('identifier', $page->getIdentifier())->addStoreFilter($target_store_id);
754
+ if ($cms_page_collection->count() == 0) {
755
+ $translated_page = Mage::getModel('cms/page');
756
+ $model_data = $page->getData();
757
+ unset($model_data['page_id']);
758
+ $model_data['stores'] = array($target_store_id);
759
+ } else {
760
+ $translated_page = $cms_page_collection->fetchItem();
761
+ if ($translated_page->getId() == $page->getId()) {
762
+ $translated_page = Mage::getModel('cms/page');
763
+ $model_data = $page->getData();
764
+ unset($model_data['page_id']);
765
+ $model_data['stores'] = array($target_store_id);
766
+ } else {
767
+ // Updating an existing item
768
+ $model_data = $translated_page->getData();
769
+ if (!isset($model_data['stores']) || empty($model_data['stores'])) {
770
+ $model_data['stores'] = array($target_store_id);
771
+ }
772
+ }
773
+ }
774
+ /** @var Mage_Cms_Model_Page $translated_page */
775
+ $translated_page->setData($model_data);
776
+ switch ($field_name) {
777
+ case 'content':
778
+ $translated_page->setContent(($payload['text'] ? $payload['text'] : ''));
779
+ break;
780
+ case 'meta-keywords':
781
+ $translated_page->setMetaKeywords(($payload['text'] ? $payload['text'] : ''));
782
+ break;
783
+ case 'meta-description':
784
+ $translated_page->setMetaDescription(($payload['text'] ? $payload['text'] : ''));
785
+ break;
786
+ case 'title':
787
+ $translated_page->setTitle(($payload['text'] ? $payload['text'] : ''));
788
+ break;
789
+ }
790
+ try {
791
+ $translated_page->save();
792
+ } catch (Exception $e) {
793
+ throw $e;
794
+ }
795
+
796
+ return true;
797
+ }
798
+
799
  private function _saveProductDetails($matches, $payload, $text_id) {
800
  $store_id = $matches[1];
801
  $product_id = $matches[2];
app/code/community/Transfluent/Translate/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Transfluent_Translate>
5
- <version>1.3.2</version>
6
  </Transfluent_Translate>
7
  </modules>
8
 
@@ -144,8 +144,14 @@
144
  <children>
145
  <submenu translate="title" module="transfluenttranslate">
146
  <title>Order translations by category</title>
 
147
  <action>transfluenttranslate/adminhtml_transfluentorder/orderByCategoryStep1</action>
148
  </submenu>
 
 
 
 
 
149
  </children>
150
  <sort_order>71</sort_order>
151
  <action>transfluenttranslate/adminhtml_transfluenttranslate</action>
2
  <config>
3
  <modules>
4
  <Transfluent_Translate>
5
+ <version>1.4.0</version>
6
  </Transfluent_Translate>
7
  </modules>
8
 
144
  <children>
145
  <submenu translate="title" module="transfluenttranslate">
146
  <title>Order translations by category</title>
147
+ <sort_order>1</sort_order>
148
  <action>transfluenttranslate/adminhtml_transfluentorder/orderByCategoryStep1</action>
149
  </submenu>
150
+ <submenu2 translate="title" module="transfluenttranslate">
151
+ <title>Order translations for CMS content</title>
152
+ <sort_order>2</sort_order>
153
+ <action>transfluenttranslate/adminhtml_transfluentorder/orderFromCmsStep1</action>
154
+ </submenu2>
155
  </children>
156
  <sort_order>71</sort_order>
157
  <action>transfluenttranslate/adminhtml_transfluenttranslate</action>
app/code/community/Transfluent/Translate/etc/system.xml CHANGED
@@ -109,10 +109,10 @@
109
  <comment><![CDATA[<img src="https://transfluent.com/gfx/transfluent-logo_v3.png"><br>
110
  <p>
111
  Contact <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> to setup invoicing
112
- or visit <a href="https://www.transfluent.com/my-account/">your Transfluent account page</a> to setup a credit card.
113
  </p>
114
  <strong>Support:</strong> <a href="mailto:support@transfluent.com">support@transfluent.com</a><br>
115
- <strong>Extension version:</strong> 1.3.2<br>
116
  <strong>Extension homepage:</strong> <a href="http://www.transfluent.com/products/magento/">transfluent.com/products/magento</a>
117
  ]]></comment>
118
  <fields>
109
  <comment><![CDATA[<img src="https://transfluent.com/gfx/transfluent-logo_v3.png"><br>
110
  <p>
111
  Contact <a href="mailto:sales@transfluent.com">sales@transfluent.com</a> to setup invoicing
112
+ or visit <a href="https://www.transfluent.com/my-account/#/creditcard" target="_blank">your Transfluent account page</a> to setup a credit card.
113
  </p>
114
  <strong>Support:</strong> <a href="mailto:support@transfluent.com">support@transfluent.com</a><br>
115
+ <strong>Extension version:</strong> 1.4.0<br>
116
  <strong>Extension homepage:</strong> <a href="http://www.transfluent.com/products/magento/">transfluent.com/products/magento</a>
117
  ]]></comment>
118
  <fields>
app/design/adminhtml/default/default/template/transfluent/order/category_step1.phtml CHANGED
@@ -97,462 +97,3 @@ $collision_strategy = $this->getRequest()->getParam('collision');
97
  </div>
98
  </div>
99
  </form></div>
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
- <?php
110
- print '<pre>';
111
-
112
-
113
-
114
-
115
- //var_dump(Mage::app()->getWebsites());
116
- die; // DEBUG
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
- return;
137
-
138
-
139
- $stores = Mage::app()->getStores();
140
- if (!$stores || count($stores) < 2) {
141
- ?>
142
- <div class="notification-global"
143
- style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div>
144
-
145
- <?php
146
- return;
147
- }
148
- $possible_source_languages = array();
149
- foreach ($stores AS $store) {
150
- /** @var Mage_Core_Model_Store $store */
151
- if ($this->getRequest()->getParam('store') == $store->getId()) {
152
- continue;
153
- }
154
- $possible_source_languages[] = $store;
155
- }
156
- if (empty($possible_source_languages)) {
157
- ?>
158
- <div class="notification-global"
159
- style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div>
160
- <?php
161
- return;
162
- }
163
- $store_id = $this->getRequest()->getParam('store');
164
- $current_store = Mage::app()->getStore($store_id);
165
- ?>
166
-
167
- <div style="margin-bottom: 10px;">
168
- <p>
169
- <?php echo $this->__('By ticking one or more category, you can order a translation for all products in the selected categories with a single click.'); ?>
170
- </p>
171
- <?php printf(
172
- $this->__('Translate product categories from %s into %s using %s'),
173
- $languageHelper->getSourceLanguageSelectForOrderHtml($possible_source_languages, 'source_language'),
174
- $languageHelper->getSourceLanguageSelectForOrderHtml($possible_source_languages, 'destination_language'),
175
- $languageHelper->getQualityHtml($store_id)
176
- ); ?>
177
- <button id="tf_translate_quote" title="Quote" type="button"
178
- class="scalable btn-translate"
179
- onclick="QuoteTranslation(this); ResetEstimation(); return false;">
180
- <span>
181
- <?php echo $this->__('Get quote'); ?>
182
- </span>
183
- </button>
184
- <br>
185
-
186
-
187
- <div id="tf_translate_order_result" style="display: none"
188
- style="padding: 10px;">
189
- <ul class="messages">
190
- <li class="success-msg" style="display: none"
191
- id="tf_translate_order_result_success_msg">
192
- <ul>
193
- <li>
194
- <span
195
- id="tf_translate_order_result_success_msg_caption">
196
- <?php echo $this->__('Thank you for the order!'); ?>
197
- </span>
198
- </li>
199
- </ul>
200
- </li>
201
- <div class="notification-global" style="display: none"
202
- id="tf_translate_order_result_error_msg">
203
- <div id="tf_translate_order_result_error_msg_caption">
204
- </div>
205
- </div>
206
- </ul>
207
- </div>
208
-
209
- <div id="tf_translate_get_quote_error" style="display: none"
210
- style="padding: 10px;">
211
- <div class="notification-global">
212
- <div id="tf_translate_get_quote_error_msg">
213
- </div>
214
- </div>
215
- <br>
216
- <button title="OK" type="button" class="scalable back"
217
- onclick="ResetEstimation();" style="">
218
- <span>
219
- <span>
220
- <span><?php echo $this->__('OK'); ?></span>
221
- </span>
222
- </span>
223
- </button>
224
- </div>
225
-
226
- <div id="tf_translate_form" style="padding: 10px; display: none">
227
- <div id="tf_translate_form_cost_msg" style="display: none">
228
- <?php echo $this->__(<<< 'MSG'
229
- Product details contain <span
230
- id="tf_translate_quote_words_count"></span> words to translate.
231
- Translation
232
- costs <span id="tf_translate_quote_cost"></span><span
233
- id="tf_translate_quote_currency"></span>.
234
- MSG
235
- ); ?>
236
- </div>
237
- <div id="tf_translate_form_no_content" style="display: none">
238
- <?php echo $this->__('Product details contain nothing to translate. Please choose different product fields to translate and update the quote.'); ?>
239
- </div>
240
- <br>
241
-
242
- <div id="tf_translate_form_instruction_box" style="display: none">
243
- <a href="#"
244
- onclick="$('tf_translate_form_instructions').toggle(); return false;">
245
- <?php echo $this->__('Instructions'); ?>
246
- </a>
247
- <br>
248
-
249
- <div id="tf_translate_form_instructions" style="display: none;">
250
- <textarea id="tf_translate_instructions_txt" name="instructions"
251
- cols=60 rows=4>
252
- </textarea>
253
- <br>
254
- </div>
255
- </div>
256
-
257
- <div id="tf_translate_form_product_attributes" style="display: none">
258
- - <a href="#"
259
- onclick="$('tf_translate_form_fields').toggle(); return false;">
260
- <?php echo $this->__('Product details to translate'); ?>
261
- </a>
262
- <br>
263
-
264
- <div id="tf_translate_form_fields" style="display: none;">
265
- <select multiple
266
- onchange="$('quote_action_buttons_container').hide(); $('get_new_quote_button').show();"
267
- id="fields_to_translate">
268
- </select>
269
-
270
- <div class="form-list">
271
- <p class="note">
272
- <span>
273
- <?php echo $this->__('Hold down CTRL- (PC) or Command-key (MAC) to select multiple items.'); ?>
274
- </span>
275
- </p>
276
- </div>
277
- </div>
278
-
279
- <br>
280
-
281
- <div id="tf_translate_form_force_translate"
282
- class="form-list" style="display: none">
283
- <p>
284
- <input type="checkbox" id="force_translate"
285
- name="force_translate" value='0'/>
286
- <?php echo $this->__('Force translation'); ?>
287
- </p>
288
-
289
- <p class="note">
290
- <span>
291
- <?php echo $this->__('Use this to translate content if you have local changes in the target store'); ?>
292
- </span>
293
- </p>
294
- </div>
295
-
296
- </div>
297
- <br>
298
- <span id="quote_action_buttons_container">
299
- <button title="Order" type="button" id="tf_place_order_btn"
300
- class="scalable save"
301
- onclick="OrderTranslation(this); return false;">
302
- <span>
303
- <span>
304
- <span>
305
- <?php echo $this->__('Order translation'); ?>
306
- </span>
307
- </span>
308
- </span>
309
- </button>
310
-
311
- <button title="Cancel" type="button" class="scalable cancel"
312
- onclick="ResetEstimation();" style="">
313
- <span>
314
- <span>
315
- <span>
316
- <?php echo $this->__('Cancel'); ?>
317
- </span>
318
- </span>
319
- </span>
320
- </button>
321
- </span>
322
- <span id="get_new_quote_button" style="display: none;">
323
- <button title="Get new quote" type="button" id="tf_refresh_quote_btn"
324
- class="scalable save"
325
- onclick="QuoteTranslation(this); return false;">
326
- <span>
327
- <span>
328
- <span>
329
- <?php echo $this->__('Update quote'); ?>
330
- </span>
331
- </span>
332
- </span>
333
- </button>
334
-
335
- </span>
336
- </div>
337
- </div>
338
-
339
- <!-- categories list -->
340
- <div style="margin-left: 20px;">
341
- <?php
342
- print $categoryHelper->getCategoriesHTML();
343
- ?>
344
- </div>
345
-
346
- <script type="text/javascript">
347
-
348
- /**
349
- * all categories and products inside (used to get quote data)
350
- */
351
- var categoryProducts = <?php print $categoryHelper->getCategoryProducts(); ?>;
352
-
353
- /**
354
- * On page load sets source and destination languages
355
- */
356
- window.onload = function () {
357
- var source = document.getElementById("source_language");
358
- var destination = document.getElementById("destination_language");
359
-
360
- ManageDestinationLanguageItem(source, destination);
361
-
362
- source.addEventListener("change", function () {
363
- ManageDestinationLanguageItem(source, destination);
364
- });
365
- };
366
-
367
- /**
368
- * Manages selection and disabling of destination language based on sourcelanguage
369
- */
370
- function ManageDestinationLanguageItem(source, destination) {
371
- var selected = source.options[source.selectedIndex].value;
372
- var destOptions = destination.getElementsByTagName("option");
373
- for (var i = 0; i < destOptions.length; i++) {
374
-
375
- destOptions[i].disabled = destOptions[i].value == selected;
376
-
377
- if (destOptions[i].className == "disabled_item") {
378
- destOptions[i].selected = true;
379
- destOptions[i].disabled = true;
380
- }
381
- }
382
- }
383
-
384
- function OrderTranslation(order_btn) {
385
-
386
- if (($('destination_language').getValue()) == "") {
387
- alert("No destination language is being selected!");
388
- return;
389
- }
390
-
391
- if (!getSelectedProducts('chk_group[]').length) {
392
- alert('No product category is selected!');
393
- return;
394
- }
395
-
396
- $(order_btn).disable();
397
-
398
- var force_translate = document.getElementById('force_translate').value;
399
-
400
- new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/order') ?>', {
401
- method: 'post',
402
- parameters: {
403
- 'store_from': $('source_language').getValue(),
404
- 'store_to': $('destination_language').getValue(),
405
- 'level': $('tf_translate_level').getValue(),
406
- 'product_id': JSON.stringify(getSelectedProducts('chk_group[]')),
407
- 'instructions': $('tf_translate_instructions_txt').getValue(),
408
- 'force_translate': force_translate,
409
- 'fields_to_translate[]': $('fields_to_translate').getValue()
410
- },
411
- onSuccess: function (response) {
412
- ResetEstimation();
413
- var text = response.responseText;
414
- if (response.responseText.isJSON()) {
415
- var response_obj = response.responseText.evalJSON();
416
- hideElementById('tf_translate_form');
417
- showElementById('tf_translate_order_result');
418
- if ("success" == response_obj.status) {
419
- showElementById('tf_translate_order_result_success_msg');
420
- hideElementById('tf_translate_order_result_error_msg');
421
- } else if ("error" == response_obj.status) {
422
- showElementById('tf_translate_order_result_error_msg');
423
- hideElementById('tf_translate_order_result_success_msg');
424
- $('tf_translate_order_result_error_msg_caption').update(response_obj.message);
425
- }
426
- }
427
- $(order_btn).enable();
428
- },
429
- onError: function (response) {
430
- alert('Failed to place order. Please try again!');
431
- }
432
- });
433
- }
434
-
435
- /**
436
- * reset estimation
437
- */
438
- function ResetEstimation() {
439
- $('source_language').enable();
440
- $('tf_translate_level').enable();
441
- $('tf_translate_quote').enable().show();
442
- hideElementById('tf_translate_form');
443
- hideElementById('tf_translate_order_result');
444
- hideElementById('tf_translate_order_result_error_msg');
445
- hideElementById('tf_translate_order_result_success_msg');
446
- }
447
-
448
- /**
449
- * get quote for translation
450
- */
451
- function QuoteTranslation(quote_btn) {
452
-
453
- if (($('destination_language').getValue()) == "") {
454
- alert("No destination language is being selected!");
455
- return;
456
- }
457
-
458
- if (!getSelectedProducts('chk_group[]').length) {
459
- alert('No product category is selected!');
460
- return;
461
- }
462
-
463
- var fields_to_translate = [];
464
- if ($('fields_to_translate')) {
465
- fields_to_translate = $('fields_to_translate').getValue();
466
- }
467
- var force_translate = 0;
468
- if ($('force_translate') && $('force_translate').getValue != "") {
469
- force_translate = $('force_translate').getValue();
470
- }
471
-
472
- var params = {
473
- 'store_from': $('source_language').getValue(),
474
- 'store_to': '<?=$this->getRequest()->getParam('store')?>',
475
- 'level': $('tf_translate_level').getValue(),
476
- 'force_translate': force_translate,
477
- 'product_id': JSON.stringify(getSelectedProducts('chk_group[]'))
478
- };
479
-
480
- if (null != fields_to_translate) {
481
- params['fields_to_translate[]'] = fields_to_translate;
482
- }
483
-
484
- if ($('tf_translate_instructions_txt')) {
485
- params.instructions = $('tf_translate_instructions_txt').getValue();
486
- }
487
-
488
- new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_quote') ?>', {
489
- method: 'post',
490
- parameters: params,
491
- onSuccess: function (response) {
492
- $('source_language').disable();
493
- $('tf_translate_level').disable();
494
- $('tf_translate_quote').hide();
495
- var text = response.responseText;
496
- if (response.responseText.isJSON()) {
497
- var responseObj = response.responseText.evalJSON();
498
- $('quote_action_buttons_container').show();
499
- $('get_new_quote_button').hide();
500
- if (responseObj.status === "success") {
501
- showElementById('tf_translate_form');
502
- updateQuoteForm(responseObj);
503
- } else if (responseObj.status === "error") {
504
- document.getElementById("tf_translate_get_quote_error_msg").innerText = responseObj.message;
505
- showElementById('tf_translate_get_quote_error');
506
- }
507
- }
508
- },
509
- onError: function () {
510
- alert('Failed to estimate costs. Please try again!');
511
- }
512
- });
513
- }
514
-
515
- /**
516
- * update quote form by json object got from get_quote back-end
517
- * @param obj
518
- */
519
- function updateQuoteForm(obj) {
520
-
521
- // update and show price and wordcount
522
- if (typeof(obj.cost) !== 'undefined' && typeof(obj.currency) !== 'undefined' && typeof(obj.wordCount) !== 'undefined') {
523
- document.getElementById('tf_translate_quote_words_count').innerHTML = obj.wordCount;
524
- document.getElementById('tf_translate_quote_currency').innerHTML = obj.currency;
525
- document.getElementById('tf_translate_quote_cost').innerHTML = obj.cost;
526
- showElementById('tf_translate_form_cost_msg');
527
- hideElementById('tf_translate_form_no_content');
528
- } else {
529
- hideElementById('tf_translate_form_cost_msg');
530
- showElementById('tf_translate_form_no_content');
531
- }
532
-
533
- // update and show instruction box
534
- if (typeof(obj.instruction) !== 'undefined') {
535
- document.getElementById('tf_translate_instructions_txt').innerHTML = obj.instruction;
536
- showElementById('tf_translate_form_instruction_box');
537
- }
538
-
539
- // generate product attributes
540
- if (typeof(obj.productAttributes) !== 'undefined') {
541
- document.getElementById('fields_to_translate').innerHTML = buildSelectOptions(obj.productAttributes);
542
- showElementById('tf_translate_form_product_attributes');
543
- }
544
-
545
- // enable force translate
546
- if (obj.translationFields.length == 0 || obj.fieldsAlreadyTranslated != null || obj.forceTranslate == true) {
547
- document.getElementById('force_translate').value = 1;
548
- if (obj.forceTranslate == true) {
549
- document.getElementById('force_translate').checked = true;
550
-
551
- }
552
- showElementById('tf_translate_form_force_translate');
553
- } else {
554
- document.getElementById('force_translate').value = 0;
555
- }
556
- }
557
- </script>
558
- <?php print memory_get_peak_usage();
97
  </div>
98
  </div>
99
  </form></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/transfluent/order/cms_step1.phtml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
3
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
4
+
5
+ /** @var Transfluent_Translate_Helper_Category $categoryHelper */
6
+ $categoryHelper = Mage::helper('transfluenttranslate/category');
7
+
8
+ $level = $this->getRequest()->getParam('level');
9
+ $source = $this->getRequest()->getParam('source');
10
+ $target = $this->getRequest()->getParam('target');
11
+ $collision_strategy = $this->getRequest()->getParam('collision');
12
+ ?>
13
+
14
+ <div class="content-header">
15
+ <h3 class="icon-head head-products"><?= $languageHelper->__('Order translations for CMS content') ?></h3>
16
+ </div>
17
+
18
+ <div style="padding: 1rem; color: #ccc; margin-top: -1rem;">
19
+ <strong style="color: black;">1. Choose source&amp;target</strong> &gt; 2. Choose CMS content &gt; 3. Get quote &gt; 4. Order!
20
+ </div>
21
+
22
+ <div class="entry-edit" style="width: 33%; min-width: 550px;">
23
+ <form action="<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep2')?>" method="post" id="edit_form"><div><input name="form_key" type="hidden" value="<?=Mage::getSingleton('core/session')->getFormKey()?>"></div><div class="entry-edit-head">
24
+ <h4 class="icon-head head-edit-form fieldset-legend">Translation options</h4>
25
+ <div class="form-buttons"></div>
26
+ </div>
27
+ <div class="fieldset " id="base_fieldset">
28
+ <div class="hor-scroll">
29
+ <table cellspacing="0" class="form-list">
30
+ <tbody>
31
+ <tr>
32
+ <td class="label"><label for="username">Translator level</label></td>
33
+ <td class="value">
34
+ <select name="level">
35
+ <option value="native" <?=($level == 'native' ? 'selected="selected"' : '')?>>Native</option>
36
+ <option value="business" <?=(!$level || $level == 'business' ? 'selected="selected"' : '')?>>Business</option>
37
+ </select>
38
+ </td>
39
+ </tr>
40
+ <?php
41
+ $website_dropdown_options = '';
42
+ $websites = Mage::app()->getWebsites();
43
+ foreach ($websites AS $website) {
44
+ /** @var Mage_Core_Model_Website $website */
45
+ $website_dropdown_options .= '<optgroup label="' . htmlspecialchars($website->getName()) . '"></optgroup>';
46
+ $website_default_store = $website->getDefaultStore();
47
+ $website_default_store_id = $website_default_store->getId();
48
+ unset($website_default_store);
49
+ $stores = $website->getStores();
50
+ foreach ($stores AS $store) {
51
+ /** @var Mage_Core_Model_Store $store */
52
+ $store_locale_code = $languageHelper->GetStoreLocale($store->getCode());
53
+ $selected_source = (!$source && $store->getId() == $website_default_store_id || $source == $store->getId());
54
+ $selected_target = ($target && $store->getId() == $target);
55
+ $website_dropdown_options .= '<option value="' . $store->getId() . '" ' . ($selected_source ? 'SOURCE-SELECTED' : '') . ($selected_target ? 'TARGET-SELECTED' : '') . '>&nbsp;&nbsp;' . htmlspecialchars($store->getName()) . ' (' . $languageHelper->getLanguageNameByCode($store_locale_code, true) . ', ' . $store_locale_code . ')</option>';
56
+ }
57
+ }
58
+ ?>
59
+ <tr>
60
+ <td class="label"><label for="firstname">Translate from</label></td>
61
+ <td class="value">
62
+ <select name="source">
63
+ <?=str_replace(array('SOURCE-SELECTED', 'TARGET-SELECTED'), array('selected="selected"', ''), $website_dropdown_options)?>
64
+ </select>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td class="label"><label for="firstname">Translate into</label></td>
69
+ <td class="value">
70
+ <select name="target">
71
+ <option></option>
72
+ <?=str_replace(array('TARGET-SELECTED', 'SOURCE-SELECTED'), array('selected="selected"', ''), $website_dropdown_options)?>
73
+ </select>
74
+ </td>
75
+ </tr>
76
+ <tr>
77
+ <td class="label"><label for="username">Existing content in target store view..</label></td>
78
+ <td class="value">
79
+ <select name="collision">
80
+ <option value="translated" <?=($collision_strategy == 'translated' ? 'selected="selected"' : '')?>>Skip: Assume any store specific value to be already translated</option>
81
+ <option value="source" <?=($collision_strategy == 'source' ? 'selected="selected"' : '')?>>Translate: Use any store specific value as source text for translation</option>
82
+ <option value="overwrite" <?=($collision_strategy == 'overwrite' ? 'selected="selected"' : '')?>>Delete: Overwrite store specific values with new translations</option>
83
+ </select>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td class="label"></td>
88
+ <td class="value" style="text-align: right;">
89
+ <button title="Next" type="submit" class="scalable save">Next</button>
90
+ </td>
91
+ </tr>
92
+ </tbody>
93
+ </table>
94
+ <p>
95
+ <i class="link-store-scope"></i> CMS pages and blocks will be saved with the same identifier as the original content but it will be associated to the target store view only. Please note that in most cases for the first round of translations, you need to choose "Translate" -option for the existing content handling because usually the main language (e.g. English) version is shown on all store views until translations are in place.<br><br><strong>Important:</strong> This tool will always send the content to be (re-)translated unless there is an <strong>exact match</strong> of previous translation. Read more: <a href="https://transfluent.zendesk.com/hc/en-us/articles/206545945-Does-Transfluent-have-translation-memory-" target="_blank">Does Transfluent have translation memory?</a>
96
+ </p>
97
+ </div>
98
+ </div>
99
+ </form></div>
app/design/adminhtml/default/default/template/transfluent/order/cms_step2.phtml ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
3
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
4
+
5
+ /** @var Transfluent_Translate_Helper_Category $categoryHelper */
6
+ $categoryHelper = Mage::helper('transfluenttranslate/category');
7
+
8
+ $level = $this->getRequest()->getParam('level');
9
+ $source = $this->getRequest()->getParam('source');
10
+ $target = $this->getRequest()->getParam('target');
11
+ $collision_strategy = $this->getRequest()->getParam('collision');
12
+ $form_submitted = $this->getRequest()->getParam('form_submitted');
13
+ $translate_pages = $this->getRequest()->getParam('translate_pages');
14
+ $translate_blocks = $this->getRequest()->getParam('translate_blocks');
15
+ ?>
16
+
17
+ <div class="content-header">
18
+ <h3 class="icon-head head-products"><?= $languageHelper->__('Order translations for CMS content') ?></h3>
19
+ </div>
20
+
21
+ <div style="padding: 1rem; color: #ccc; margin-top: -1rem;">
22
+ <span style="color: #666;">1. Choose source&amp;target</span> &gt; <strong style="color: black;">2. Choose CMS content</strong> &gt; 3. Get quote &gt; 4. Order!
23
+ </div>
24
+
25
+ <div class="entry-edit" style="width: 33%; min-width: 550px;">
26
+ <form action="<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep3')?>" method="post" id="edit_form"><div><input name="form_key" type="hidden" value="<?=Mage::getSingleton('core/session')->getFormKey()?>"></div><div class="entry-edit-head">
27
+ <h4 class="icon-head head-edit-form fieldset-legend">Select CMS pages and static blocks to translate</h4>
28
+ <div class="form-buttons"></div>
29
+ </div>
30
+ <div class="fieldset " id="base_fieldset">
31
+ <input type="hidden" name="source" value="<?=$source?>">
32
+ <input type="hidden" name="target" value="<?=$target?>">
33
+ <input type="hidden" name="level" value="<?=$level?>">
34
+ <input type="hidden" name="form_submitted" value="1">
35
+ <input type="hidden" name="collision" value="<?=$collision_strategy?>">
36
+ <div class="hor-scroll">
37
+ <?php
38
+ if (!$form_submitted || ($form_submitted && $translate_blocks && $translate_pages)) {
39
+ ?>
40
+ <div>
41
+ <label><input type="checkbox" name="translate_pages" value="1" checked="checked"> Translate <strong>ALL</strong> CMS pages</label><br>
42
+ <label><input type="checkbox" name="translate_blocks" value="1" checked="checked"> Translate <strong>ALL</strong> CMS blocks</label>
43
+ </div>
44
+ <?php
45
+ } else {
46
+ ?>
47
+ <table>
48
+ <thead style="font-weight: bold;">
49
+ <tr><td>Select pages</td><td>Select blocks</td></tr>
50
+ </thead>
51
+ <tbody>
52
+ <?php
53
+ $cms_block_model = Mage::getModel('cms/block');
54
+ /** @var Mage_Cms_Model_Block $cms_block_model */
55
+ $cms_block_collection = $cms_block_model->getCollection();
56
+ /** @var Mage_Cms_Model_Resource_Block_Collection $cms_block_collection */
57
+ $cms_block_collection->addFilter('is_active', 1)->addStoreFilter($source);
58
+ $cms_blocks = array();
59
+ while($cms_block = $cms_block_collection->fetchItem()) {
60
+ /** @var Mage_Cms_Model_Block $cms_block */
61
+ if (!$cms_block || $cms_block->isEmpty() || $cms_block->isObjectNew()) {
62
+ break;
63
+ }
64
+ $cms_block = $cms_block->load($cms_block->getId()); // Load item so "stores" value get set
65
+ if (!is_array($cms_block->stores) || (!in_array((string)$source, $cms_block->stores) && !in_array("0", $cms_block->stores))) {
66
+ continue;
67
+ }
68
+ $cms_blocks[] = array('id' => $cms_block->getId(), 'title' => $cms_block->getTitle(), 'identifier' => $cms_block->getIdentifier());
69
+ }
70
+ $cms_page_model = Mage::getModel('cms/page');
71
+ /** @var Mage_Cms_Model_Page $cms_page_model */
72
+ $cms_page_collection = $cms_page_model->getCollection();
73
+ /** @var Mage_Cms_Model_Resource_Page_Collection $cms_page_collection */
74
+ $cms_page_collection->addFilter('is_active', 1)->addStoreFilter($source);
75
+ $cms_pages = array();
76
+ while($cms_page = $cms_page_collection->fetchItem()) {
77
+ /** @var Mage_Cms_Model_Page $cms_page */
78
+ if (!$cms_page || $cms_page->isEmpty() || $cms_page->isObjectNew()) {
79
+ break;
80
+ }
81
+ $cms_page = $cms_page->load($cms_page->getId()); // Load item so "stores" value get set
82
+ if (!is_array($cms_page->store_id) || (!in_array((string)$source, $cms_page->store_id) && !in_array("0", $cms_page->store_id))) {
83
+ continue;
84
+ }
85
+ $cms_page_url = Mage::app()->getStore($source)->getUrl($cms_page->getIdentifier());
86
+ $cms_pages[] = array('id' => $cms_page->getId(), 'title' => $cms_page->getTitle(), 'url' => $cms_page_url);
87
+ }
88
+
89
+ while (count($cms_blocks) + count($cms_pages)) {
90
+ print '<tr>';
91
+ $page_arr = array_shift($cms_pages);
92
+ print '<td>';
93
+ if ($page_arr) {
94
+ print '<label><input type="checkbox" ' . ($translate_pages ? 'checked="checked"' : '') . ' name="cms_page_ids[]" value="' . $page_arr['id'] . '"> <a href="' . htmlspecialchars($page_arr['url']) . '" target="_blank">' . htmlspecialchars($page_arr['title']) . '</a></label>';
95
+ }
96
+ print '</td>';
97
+ $block_arr = array_shift($cms_blocks);
98
+ print '<td>';
99
+ if ($block_arr) {
100
+ print '<label><input type="checkbox" ' . ($translate_blocks ? 'checked="checked"' : '') . ' name="cms_block_ids[]" value="' . $block_arr['id'] . '"> ' . htmlspecialchars($block_arr['title']) . ' (' . htmlspecialchars($block_arr['identifier']) . ')</label>';
101
+ }
102
+ print '</td>';
103
+ print '</tr>';
104
+ }
105
+ ?>
106
+ </tbody>
107
+ </table>
108
+ <?php
109
+ }
110
+ ?>
111
+
112
+ <div style="margin: 1.5rem 0;">
113
+ <button title="Back" type="button" class="scalable back" onclick="$(this).up('form').writeAttribute('action', '<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep1')?>').submit(); return false;">Back</button>
114
+ <button title="Next" type="submit" class="scalable save">Next</button>
115
+ </div>
116
+
117
+ <p>
118
+ <i class="link-store-scope"></i> CMS pages and blocks will be translated from selected source store. The translated pages and blocks will be saved with the same identifier but they will be associated with the target store view only.
119
+ </p>
120
+ </div>
121
+ </div>
122
+ </form></div>
app/design/adminhtml/default/default/template/transfluent/order/cms_step3.phtml ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
3
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
4
+
5
+ /** @var Transfluent_Translate_Helper_Category $categoryHelper */
6
+ $categoryHelper = Mage::helper('transfluenttranslate/category');
7
+
8
+ $level = $this->getRequest()->getParam('level');
9
+ $source = $this->getRequest()->getParam('source');
10
+ $target = $this->getRequest()->getParam('target');
11
+ $collision_strategy = $this->getRequest()->getParam('collision');
12
+ $instructions = $this->getRequest()->getParam('instructions') ? $this->getRequest()->getParam('instructions') : '';
13
+ $translate_pages = $this->getRequest()->getParam('translate_pages');
14
+ $translate_blocks = $this->getRequest()->getParam('translate_blocks');
15
+
16
+ $quote_id = $this->getData('quote_id') ? $this->getData('quote_id') : $this->getRequest()->getParam('quote_id');
17
+ ?>
18
+
19
+ <div class="content-header">
20
+ <h3 class="icon-head head-products"><?= $languageHelper->__('Order translations for CMS content') ?></h3>
21
+ </div>
22
+
23
+ <div style="padding: 1rem; color: #ccc; margin-top: -1rem;">
24
+ <span style="color: #666;">1. Choose source&amp;target</span> &gt; <span style="color: #666;">2. Choose CMS content</span> &gt; <strong style="color: black;">3. Get quote</strong> &gt; 4. Order!
25
+ </div>
26
+
27
+ <div class="entry-edit" style="width: 33%; min-width: 550px;">
28
+ <form action="<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep4')?>" method="post" id="edit_form"><div><input name="form_key" type="hidden" value="<?=Mage::getSingleton('core/session')->getFormKey()?>"></div><div class="entry-edit-head">
29
+ <h4 class="icon-head head-edit-form fieldset-legend">Get a quote</h4>
30
+ <div class="form-buttons"></div>
31
+ </div>
32
+ <div class="fieldset " id="base_fieldset">
33
+ <div class="hor-scroll">
34
+ <input type="hidden" name="source" id="source" value="<?=$source?>">
35
+ <input type="hidden" name="target" id="target" value="<?=$target?>">
36
+ <input type="hidden" name="level" id="level" value="<?=$level?>">
37
+ <input type="hidden" name="quote_id" id="quote_id" value="<?=$quote_id?>">
38
+ <input type="hidden" name="collision" id="collision" value="<?=$collision_strategy?>">
39
+ <input type="hidden" name="translate_pages" value="<?=$translate_pages?>">
40
+ <input type="hidden" name="translate_blocks" value="<?=$translate_blocks?>">
41
+
42
+ <div id="quote_canvas" style="margin-bottom: 1rem;">
43
+ Loading..
44
+ </div>
45
+
46
+ <div id="quote_instructions" style="margin-top: 2rem; margin-bottom: 1rem; display: none;">
47
+ <label><strong>Instructions to translators (e.g. translation tone, target audience etc.)</strong><br>
48
+ <textarea name="instructions" rows="4" cols="75"><?=htmlspecialchars($instructions)?></textarea></label><br>
49
+ </div>
50
+
51
+ <?php
52
+ if ($level) {
53
+ // Missing some POST-data, such as level, hints that the quote was restored from an external link -> don't allow going back
54
+ ?><button title="Back" type="button" class="scalable back" onclick="$(this).up('form').writeAttribute('action', '<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep2')?>').submit(); return false;">Back</button><?php
55
+ }
56
+ ?>
57
+ <button title="Refresh" id="quote_refresh_btn" type="submit" class="scalable save">Refresh</button>
58
+ <button title="Order" id="quote_order_btn" type="submit" class="scalable save" onclick="OrderClick(this); return false;" disabled="disabled">Order</button>
59
+
60
+ <p>
61
+ <!-- <i class="link-store-scope"></i> CMS pages and blocks will be translated from selected source store. The translated pages and blocks will be saved with the same identifier but they will be associated with the target store view only. -->
62
+ </p>
63
+ </div>
64
+ </div>
65
+ </form></div>
66
+
67
+
68
+ <script>
69
+ function OrderClick(element) {
70
+ if (!confirm('Are you sure?')) {
71
+ return;
72
+ }
73
+ $(element).up('form').writeAttribute('action', '<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep5')?>').submit();
74
+ }
75
+
76
+ document.observe("dom:loaded", function() {
77
+ var instructions_box = $('quote_instructions');
78
+ var order_btn = $('quote_order_btn');
79
+ order_btn.hide();
80
+ var refresh_btn = $('quote_refresh_btn');
81
+ refresh_btn.hide();
82
+ var PollerFunction = function() {
83
+ new Ajax.Request('<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep3')?>', {
84
+ parameters: {quote_id: $F('quote_id')},
85
+ onSuccess: function (xhr) {
86
+ var response = xhr.responseJSON;
87
+ $('quote_canvas').update(response.status);
88
+ switch (response.status_code) {
89
+ case "0":
90
+ case "1":
91
+ order_btn.hide();
92
+ instructions_box.hide();
93
+ refresh_btn.show();
94
+ setTimeout(PollerFunction, 2500);
95
+ break;
96
+ case "2":
97
+ order_btn.show().removeAttribute('disabled');
98
+ refresh_btn.hide();
99
+ instructions_box.show();
100
+ break;
101
+ case "3":
102
+ order_btn.hide();
103
+ instructions_box.hide();
104
+ break;
105
+ default:
106
+ order_btn.hide();
107
+ refresh_btn.show();
108
+ instructions_box.hide();
109
+ quote_fields.hide();
110
+ break;
111
+ }
112
+ }
113
+ });
114
+ };
115
+ PollerFunction();
116
+
117
+ });
118
+ </script>
119
+
app/design/adminhtml/default/default/template/transfluent/order/cms_step5.phtml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
3
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
4
+
5
+ $fork_id = $this->getData('fork_id');
6
+ $quote_id = $this->getData('quote_id');
7
+ ?>
8
+
9
+ <div class="content-header">
10
+ <h3 class="icon-head head-products"><?= $languageHelper->__('Order translations for CMS content') ?></h3>
11
+ </div>
12
+
13
+ <div style="padding: 1rem; color: #ccc; margin-top: -1rem;">
14
+ <span style="color: #666;">1. Choose source&amp;target</span> &gt; <span style="color: #666;">2. Choose CMS content</span> &gt; <span style="color: #666;">3. Get quote</span> &gt; <strong style="color: black;">4. Order!</strong>
15
+ </div>
16
+
17
+ <div class="entry-edit" style="width: 33%; min-width: 550px;">
18
+ <div class="entry-edit-head">
19
+ <h4 class="icon-head head-edit-form fieldset-legend">Order</h4>
20
+ <div class="form-buttons"></div>
21
+ </div>
22
+ <div class="fieldset " id="base_fieldset">
23
+ <input type="hidden" name="quote_id" id="quote_id" value="<?=$quote_id?>">
24
+ <div id="quote_canvas" style="margin-bottom: 1rem;">
25
+ Loading..
26
+ </div>
27
+ <div class="hor-scroll" id="thanks" style="display: none;">
28
+ <h2>Thank you!</h2>
29
+ <p>Your order has been successfully placed. The ordered items and their progress are shown in &quot;<a href="https://www.transfluent.com/my-account/" target="_blank">My Account</a>&quot; on our website.</p>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ <script>
34
+ var PollFunction = function() {
35
+ new Ajax.Request('<?=$this->getUrl('transfluent/adminhtml_transfluentorder/orderFromCmsStep3')?>', {
36
+ parameters: {quote_id: $F('quote_id')},
37
+ onSuccess: function (xhr) {
38
+ var response = xhr.responseJSON;
39
+ $('quote_canvas').update(response.status);
40
+ switch (response.status_code) {
41
+ case "4":
42
+ setTimeout(PollFunction, 2500);
43
+ break;
44
+ case "3":
45
+ $('thanks').show();
46
+ $('quote_canvas').hide();
47
+ break;
48
+ default:
49
+ alert('Something unexpected happened while processing the order. Please contact support@transfluent.com to resolve the situation.');
50
+ break;
51
+ }
52
+ }
53
+ });
54
+ };
55
+ document.observe("dom:loaded", PollFunction);
56
+ </script>
57
+
app/design/adminhtml/default/default/template/transfluent/order/listing.phtml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Transfluent_Translate_Helper_Languages $languageHelper */
3
+ $languageHelper = Mage::helper('transfluenttranslate/languages');
4
+ ?>
5
+ <div class="content-header">
6
+ <h3 class="icon-head head-products"><?=$languageHelper->__('Translate your Magento store') ?></h3>
7
+ </div>
8
+
9
+ <p>Transfluent's translation extension for Magento helps you to translate your webstore into multiple languages.<br>Read more about this extension <a href="https://www.transfluent.com/products/magento/" target="_blank">here</a>.</p>
10
+
11
+ <p>Your orders will be listed under your account. Visit <a href="https://www.transfluent.com/my-account/" target="_blank">My Account</a> page.</p>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Transfluent</name>
4
- <version>1.3.2</version>
5
  <stability>stable</stability>
6
  <license>MIT</license>
7
  <channel>community</channel>
@@ -18,11 +18,11 @@
18
  <description>&lt;p&gt;The Transfluent plugin automates the process of translating product and category information using human translators. Magento admins need only to select what to translate and click order.&lt;/p&gt;&#xD;
19
  &#xD;
20
  &lt;p&gt;Translating content is handled in our backend using a vast network of professional translators.&lt;/p&gt;</description>
21
- <notes>Fixes an issue with stores in another domain</notes>
22
  <authors><author><name>Transfluent Ltd</name><user>Transfluent</user><email>coders@transfluent.com</email></author></authors>
23
- <date>2015-07-24</date>
24
- <time>16:17:02</time>
25
- <contents><target name="magecommunity"><dir name="Transfluent"><dir name="Translate"><dir name="Block"><file name="Account.php" hash="65a7a12e2ad88a5c4ba14b6c7c72fd03"/><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><file name="Grid.php" hash="d2827c5587a2bb7c8664ff92c3dcf5d7"/><dir name="Renderer"><file name="Language.php" hash="cfc3a15752ecc6f7aab870ea6834c1df"/><file name="LanguagePair.php" hash="8d1c1959b44b487570d135eb5758a63b"/><file name="Level.php" hash="4a8f278da146ce9c8108758924bea667"/><file name="SourceText.php" hash="23c33835a99e64d575b101491774ed89"/><file name="Store.php" hash="4639d9f82bb498e57842a83110573e0c"/></dir></dir></dir><dir name="Tag"><dir name="Tag"><file name="Grid.php" hash="24647d2a73089769f664f7ae8f686597"/></dir></dir><dir name="Transfluentorder"><dir name="Edit"><file name="Form.php" hash="17fc3866562d4820c251ed17cc154b4d"/><dir name="Tab"><file name="Form.php" hash="3d45b7754d0044de84f6d40cb4cca9bf"/></dir><file name="Tabs.php" hash="5654a57d38cb31fb7159ffea72380adb"/></dir><file name="Edit.php" hash="e4a7206b94ec73e6573e62d22efc61ba"/></dir><file name="Transfluentorder.php" hash="eb38c2db57bb8b66edb169d38eb55a47"/><dir name="Transfluenttranslate"><dir name="Edit"><file name="Form.php" hash="9e9d2152d4dd8fe936558a88afd1c554"/><dir name="Tab"><file name="Form.php" hash="d6bb7a75b800f0dfb9a85d6b8547d3d2"/></dir><file name="Tabs.php" hash="1e4e31e2e4be31918e4db4d677092759"/></dir><file name="Edit.php" hash="596dc94ba740e312ad1ea8a3a86bdc43"/><file name="Grid.php" hash="275f7dd4f8abb376a51bab8ee815f8f9"/></dir><file name="Transfluenttranslate.php" hash="c9a69e2dc7bb9ded6a61db0988b4842f"/></dir><file name="Estimate.php" hash="bc70c44df7c0522dc56d2039ce73dc64"/><file name="Help.php" hash="1c6779b04425381242c053baf54cac1f"/><file name="Loginform.php" hash="af3b1a47ef8c35341e439b66bce88293"/><file name="Regform.php" hash="15cf4754d6c565618566edbaee80019b"/><file name="Translblock.php" hash="8008b680d4bdbeb7b2e51a3522ac282a"/></dir><dir name="Exception"><file name="Base.php" hash="e0ab547033d95d94820a5cbd58dea6f5"/><file name="EBackendCustomerHasNoBillingAgreement.php" hash="87f798c9e376b2392f33005181028e6b"/><file name="EFailedToUpdateOrder.php" hash="4261e774331f5e68864409c687e87e84"/><file name="EInvalidInput.php" hash="9e68fc972d84da619bc0f59a0309c673"/><file name="EInvalidJob.php" hash="be82fd6fe0c1dbc88be57fa4fd923196"/><file name="EInvalidTagFormat.php" hash="c8ac44aaec31e4ab77655ab85434724b"/><file name="ELanguagePairNotSupported.php" hash="696af3edef69e5ef009bbbd766db97ae"/><file name="ETagNotFound.php" hash="6bc8d1f2a8a5cbdfa9e83be92532e159"/><file name="ETransfluentAuthenticationExpired.php" hash="31d78696b92490440689d517ce3961ad"/><file name="ETransfluentAuthenticationExpiredBase.php" hash="5f31f311c1242c956dbe03ed56b89e8e"/><file name="ETransfluentInvalidInputTags.php" hash="d7e056e164a93a6fd9f9cffbc31664f8"/><file name="ETransfluentNothingToTranslate.php" hash="6b9aef0ccc8848dbbe33e4d55742a789"/><file name="ETransfluentOrderFail.php" hash="019f6eea7ea672217a6297ad1028ed02"/><file name="ETransfluentProductHasNoFieldsToTranslate.php" hash="324c6a7f92a4b2367ad9253aae319aa2"/><file name="ETransfluentProductNotFound.php" hash="d1ae6d72c99ba0061c3972e56f7508c1"/><file name="ETransfluentSomeSelectedProductsNotFound.php" hash="aaa71cede2f1136e8f6700f35bb3c541"/><file name="ETransfluentTagsNothingToTranslate.php" hash="aaec4494fcfa5f5801cc41d2488063b2"/><file name="ETransfluentUnknownBackendResponse.php" hash="8b88d91c6069383091b46416236fb516"/><file name="ETransfluentUnknownError.php" hash="f27e0198db51ae862cc69d969238acff"/><file name="ETransfluentUnknownErrorNoEstimate.php" hash="714d3ad48595f0a7f271ff4d6e41d5b7"/><file name="ETransfluentUnknownErrorTags.php" hash="6b56cfb2b97bed42edaff02e409ded3e"/><file name="EUnauthorized.php" hash="eb1ca081eebdc497cde30cd85337bc6e"/></dir><dir name="Helper"><file name="Category.php" hash="cfd0a78eb787b2c63e5d3323c41e0559"/><file name="Constant.php" hash="76af7760107c984a86a8522d08f33529"/><file name="Data.php" hash="115f604df2570d512d73c45eb272588b"/><file name="Languages.php" hash="7f14a01e59b803135e037c9be733e190"/><file name="Product.php" hash="ee04f0c62cdeef260c677cd1fc363041"/><file name="Tag.php" hash="aba096e9a6207e7f2055db4733c1b839"/><file name="Text.php" hash="4e5c084ac4e849d6fe2614dfef77c932"/><file name="Util.php" hash="2db7fdba0b945821e12746c45fb6bf9b"/></dir><dir name="Model"><file name="AttributeName.php" hash="97619966fb9c04b031d2cae5147fdb21"/><file name="AttributeOption.php" hash="39007a2e2821e5853b6cfefe0e1a1c17"/><dir name="Base"><file name="Backendclient.php" hash="17ffbd5d70635af0b8748f445e914922"/></dir><file name="CategoryDetail.php" hash="3a0ce226c17ef8280ca9001c77e0d275"/><dir name="Config"><dir name="Source"><file name="Fromlang.php" hash="600bdc90cb5a08d36003ea651ee398c2"/><file name="Language.php" hash="dcbd7cc51695c71fa0da6da25e0d52d8"/><file name="Quality.php" hash="73987e05216bb54d3b483d751888e602"/></dir></dir><file name="Debugutil.php" hash="3542cff301f9fc0d69072068c384acb3"/><dir name="Mysql4"><dir name="Transfluenttranslate"><file name="Collection.php" hash="80ebe484ed7a4dee8980b4d6c03d1425"/></dir><file name="Transfluenttranslate.php" hash="bef2f82a3c2d2fd25031c654026bdc34"/></dir><file name="Observer.php" hash="96ca21eaefbf03ea6a84cfa1179d4c93"/><file name="ProductDetail.php" hash="5b9a5ce790576fe19e33fbbc63554a24"/><file name="TagName.php" hash="8d59f540cc0f1290b419f95f7dabe7c6"/><file name="Transfluentorder.php" hash="9dd3a64c16d95f7df151be2937a6d09c"/><file name="Transfluenttranslate.php" hash="d973756d579d415cd11033acb7669555"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="3a259d4e68c2d8ca7ca0cccf9db2a792"/><file name="TransfluentorderController.php" hash="389dae6b4590a162c7ea2363d10e1b46"/><file name="TransfluenttranslateController.php" hash="eca8e84b5e4f0a1ef0125894204303c6"/></dir><file name="TranslationController.php" hash="59cd96e1a071cc62d3262bccb09785e4"/></dir><dir name="etc"><file name="config.xml" hash="44a82e34c8126cf280ee54581ff6045e"/><file name="system.xml" hash="98ff9f547e86b35419bfb7dac5dcdfc4"/></dir><dir name="sql"><dir name="transfluenttranslate_setup"><file name="mysql4-install-1.1.0.php" hash="1691b91c29d66284b51583bf47e5c9ec"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="transfluent.xml" hash="92accb97ee4a7c710ef46e01d1307f83"/></dir><dir name="template"><dir name="transfluent"><dir name="account"><file name="action.phtml" hash="dae17137e83be4001f25997892e49901"/><file name="create.phtml" hash="5b51d4a6f3f444494fe3b053c6f96463"/><file name="logged.phtml" hash="6f024c314550b3f378e5d8399984b082"/><file name="login.phtml" hash="06acb7c890315c53937a1dd5f90275a6"/></dir><file name="estimate.phtml" hash="f2b85bb6943c7ff335d45e2401e0b541"/><file name="estimate_section.phtml" hash="1d5a6c511ae63f85f490b52be4be5dc1"/><dir name="order"><file name="category_step1.phtml" hash="9d529128723ac3ec23dff9e75e73cc41"/><file name="category_step2.phtml" hash="5b8a13b62a02778dc2c834e0ed8e9ccc"/><file name="category_step3.phtml" hash="bd8ad6b696d3c4fa11e842042c2edf18"/><file name="category_step4.phtml" hash="7d90c964cd63ee259f366de2823dcdd6"/><file name="category_step5.phtml" hash="44883dd35c420513f052852faa96bd96"/></dir><dir name="product"><dir name="attributes"><file name="edit.phtml" hash="5c2e06cb7b18b6cb34dd09398e0690cb"/></dir><dir name="category"><file name="edit.phtml" hash="acb8acba1981d3f764d120a62a4a70a7"/></dir><file name="edit.phtml" hash="fb6e94f86ba351d045d8516cc244577e"/><file name="index.phtml" hash="7ea9b53f06a8045e19d4727c41059d58"/></dir><dir name="tag"><dir name="tag"><file name="index.phtml" hash="d672d3415faa28fc85406e537b689b3c"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Transfluent_Translate.xml" hash="21fbc30a1cba6c2b86b262439eee8ed3"/></dir></target><target name="mageweb"><dir name="js"><dir name="transfluent"><file name="actions.js" hash="471135bf9f5941d0e22d11aa726bfc3b"/><file name="lib.js" hash="0f1029e5a4a1c1e88ca2bb8304bc34e8"/></dir></dir></target></contents>
26
  <compatible/>
27
- <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><extension><name>Core</name><min></min><max></max></extension><extension><name>curl</name><min></min><max></max></extension><extension><name>json</name><min></min><max></max></extension></required></dependencies>
28
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Transfluent</name>
4
+ <version>1.4.0</version>
5
  <stability>stable</stability>
6
  <license>MIT</license>
7
  <channel>community</channel>
18
  <description>&lt;p&gt;The Transfluent plugin automates the process of translating product and category information using human translators. Magento admins need only to select what to translate and click order.&lt;/p&gt;&#xD;
19
  &#xD;
20
  &lt;p&gt;Translating content is handled in our backend using a vast network of professional translators.&lt;/p&gt;</description>
21
+ <notes>Added translation support for CMS content</notes>
22
  <authors><author><name>Transfluent Ltd</name><user>Transfluent</user><email>coders@transfluent.com</email></author></authors>
23
+ <date>2015-09-25</date>
24
+ <time>09:52:03</time>
25
+ <contents><target name="magecommunity"><dir name="Transfluent"><dir name="Translate"><dir name="Block"><file name="Account.php" hash="65a7a12e2ad88a5c4ba14b6c7c72fd03"/><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><file name="Grid.php" hash="d2827c5587a2bb7c8664ff92c3dcf5d7"/><dir name="Renderer"><file name="Language.php" hash="cfc3a15752ecc6f7aab870ea6834c1df"/><file name="LanguagePair.php" hash="8d1c1959b44b487570d135eb5758a63b"/><file name="Level.php" hash="4a8f278da146ce9c8108758924bea667"/><file name="SourceText.php" hash="23c33835a99e64d575b101491774ed89"/><file name="Store.php" hash="4639d9f82bb498e57842a83110573e0c"/></dir></dir></dir><dir name="Tag"><dir name="Tag"><file name="Grid.php" hash="24647d2a73089769f664f7ae8f686597"/></dir></dir><dir name="Transfluentorder"><dir name="Edit"><file name="Form.php" hash="17fc3866562d4820c251ed17cc154b4d"/><dir name="Tab"><file name="Form.php" hash="3d45b7754d0044de84f6d40cb4cca9bf"/></dir><file name="Tabs.php" hash="5654a57d38cb31fb7159ffea72380adb"/></dir><file name="Edit.php" hash="e4a7206b94ec73e6573e62d22efc61ba"/></dir><file name="Transfluentorder.php" hash="eb38c2db57bb8b66edb169d38eb55a47"/><dir name="Transfluenttranslate"><dir name="Edit"><file name="Form.php" hash="9e9d2152d4dd8fe936558a88afd1c554"/><dir name="Tab"><file name="Form.php" hash="d6bb7a75b800f0dfb9a85d6b8547d3d2"/></dir><file name="Tabs.php" hash="1e4e31e2e4be31918e4db4d677092759"/></dir><file name="Edit.php" hash="596dc94ba740e312ad1ea8a3a86bdc43"/><file name="Grid.php" hash="275f7dd4f8abb376a51bab8ee815f8f9"/></dir><file name="Transfluenttranslate.php" hash="c9a69e2dc7bb9ded6a61db0988b4842f"/></dir><file name="Estimate.php" hash="bc70c44df7c0522dc56d2039ce73dc64"/><file name="Help.php" hash="1c6779b04425381242c053baf54cac1f"/><file name="Loginform.php" hash="af3b1a47ef8c35341e439b66bce88293"/><file name="Regform.php" hash="15cf4754d6c565618566edbaee80019b"/><file name="Translblock.php" hash="8008b680d4bdbeb7b2e51a3522ac282a"/></dir><dir name="Exception"><file name="Base.php" hash="e0ab547033d95d94820a5cbd58dea6f5"/><file name="EBackendCustomerHasNoBillingAgreement.php" hash="87f798c9e376b2392f33005181028e6b"/><file name="EFailedToUpdateOrder.php" hash="4261e774331f5e68864409c687e87e84"/><file name="EInvalidInput.php" hash="9e68fc972d84da619bc0f59a0309c673"/><file name="EInvalidJob.php" hash="be82fd6fe0c1dbc88be57fa4fd923196"/><file name="EInvalidTagFormat.php" hash="c8ac44aaec31e4ab77655ab85434724b"/><file name="ELanguagePairNotSupported.php" hash="696af3edef69e5ef009bbbd766db97ae"/><file name="ETagNotFound.php" hash="6bc8d1f2a8a5cbdfa9e83be92532e159"/><file name="ETransfluentAuthenticationExpired.php" hash="31d78696b92490440689d517ce3961ad"/><file name="ETransfluentAuthenticationExpiredBase.php" hash="5f31f311c1242c956dbe03ed56b89e8e"/><file name="ETransfluentInvalidInputTags.php" hash="d7e056e164a93a6fd9f9cffbc31664f8"/><file name="ETransfluentNothingToTranslate.php" hash="6b9aef0ccc8848dbbe33e4d55742a789"/><file name="ETransfluentOrderFail.php" hash="019f6eea7ea672217a6297ad1028ed02"/><file name="ETransfluentProductHasNoFieldsToTranslate.php" hash="324c6a7f92a4b2367ad9253aae319aa2"/><file name="ETransfluentProductNotFound.php" hash="d1ae6d72c99ba0061c3972e56f7508c1"/><file name="ETransfluentSomeSelectedProductsNotFound.php" hash="aaa71cede2f1136e8f6700f35bb3c541"/><file name="ETransfluentTagsNothingToTranslate.php" hash="aaec4494fcfa5f5801cc41d2488063b2"/><file name="ETransfluentUnknownBackendResponse.php" hash="8b88d91c6069383091b46416236fb516"/><file name="ETransfluentUnknownError.php" hash="f27e0198db51ae862cc69d969238acff"/><file name="ETransfluentUnknownErrorNoEstimate.php" hash="714d3ad48595f0a7f271ff4d6e41d5b7"/><file name="ETransfluentUnknownErrorTags.php" hash="6b56cfb2b97bed42edaff02e409ded3e"/><file name="EUnauthorized.php" hash="eb1ca081eebdc497cde30cd85337bc6e"/></dir><dir name="Helper"><file name="Category.php" hash="cfd0a78eb787b2c63e5d3323c41e0559"/><file name="Constant.php" hash="76af7760107c984a86a8522d08f33529"/><file name="Data.php" hash="115f604df2570d512d73c45eb272588b"/><file name="Languages.php" hash="7f14a01e59b803135e037c9be733e190"/><file name="Product.php" hash="ee04f0c62cdeef260c677cd1fc363041"/><file name="Tag.php" hash="aba096e9a6207e7f2055db4733c1b839"/><file name="Text.php" hash="4e5c084ac4e849d6fe2614dfef77c932"/><file name="Util.php" hash="2db7fdba0b945821e12746c45fb6bf9b"/></dir><dir name="Model"><file name="AttributeName.php" hash="97619966fb9c04b031d2cae5147fdb21"/><file name="AttributeOption.php" hash="39007a2e2821e5853b6cfefe0e1a1c17"/><dir name="Base"><file name="Backendclient.php" hash="0d0c07e0b59915739b8a341de2e7a6d4"/></dir><file name="CategoryDetail.php" hash="3a0ce226c17ef8280ca9001c77e0d275"/><dir name="Config"><dir name="Source"><file name="Fromlang.php" hash="600bdc90cb5a08d36003ea651ee398c2"/><file name="Language.php" hash="dcbd7cc51695c71fa0da6da25e0d52d8"/><file name="Quality.php" hash="73987e05216bb54d3b483d751888e602"/></dir></dir><file name="Debugutil.php" hash="3542cff301f9fc0d69072068c384acb3"/><dir name="Mysql4"><dir name="Transfluenttranslate"><file name="Collection.php" hash="80ebe484ed7a4dee8980b4d6c03d1425"/></dir><file name="Transfluenttranslate.php" hash="bef2f82a3c2d2fd25031c654026bdc34"/></dir><file name="Observer.php" hash="96ca21eaefbf03ea6a84cfa1179d4c93"/><file name="ProductDetail.php" hash="5b9a5ce790576fe19e33fbbc63554a24"/><file name="TagName.php" hash="8d59f540cc0f1290b419f95f7dabe7c6"/><file name="Transfluentorder.php" hash="9dd3a64c16d95f7df151be2937a6d09c"/><file name="Transfluenttranslate.php" hash="d973756d579d415cd11033acb7669555"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="3a259d4e68c2d8ca7ca0cccf9db2a792"/><file name="TransfluentorderController.php" hash="773edc9bc7386db10358c0f8729d4e5c"/><file name="TransfluenttranslateController.php" hash="4f699d4fbde848cef6797222ca5b47dd"/></dir><file name="TranslationController.php" hash="40805e48416084b1c12de365f49accde"/></dir><dir name="etc"><file name="config.xml" hash="2276490088db6dece9384aa0435fc171"/><file name="system.xml" hash="775f4056fd1fd2a30e09d0dc9ff4707e"/></dir><dir name="sql"><dir name="transfluenttranslate_setup"><file name="mysql4-install-1.1.0.php" hash="1691b91c29d66284b51583bf47e5c9ec"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="transfluent.xml" hash="92accb97ee4a7c710ef46e01d1307f83"/></dir><dir name="template"><dir name="transfluent"><dir name="account"><file name="action.phtml" hash="dae17137e83be4001f25997892e49901"/><file name="create.phtml" hash="5b51d4a6f3f444494fe3b053c6f96463"/><file name="logged.phtml" hash="6f024c314550b3f378e5d8399984b082"/><file name="login.phtml" hash="06acb7c890315c53937a1dd5f90275a6"/></dir><file name="estimate.phtml" hash="f2b85bb6943c7ff335d45e2401e0b541"/><file name="estimate_section.phtml" hash="1d5a6c511ae63f85f490b52be4be5dc1"/><dir name="order"><file name="category_step1.phtml" hash="7a30fd5e35c0df8ac6db03607e453485"/><file name="category_step2.phtml" hash="5b8a13b62a02778dc2c834e0ed8e9ccc"/><file name="category_step3.phtml" hash="bd8ad6b696d3c4fa11e842042c2edf18"/><file name="category_step4.phtml" hash="7d90c964cd63ee259f366de2823dcdd6"/><file name="category_step5.phtml" hash="44883dd35c420513f052852faa96bd96"/><file name="cms_step1.phtml" hash="9879ec5bc7bcf00327d71432713f04b8"/><file name="cms_step2.phtml" hash="47182a2829b7fdd64cf89563edabd4a5"/><file name="cms_step3.phtml" hash="fa648f1b000175bb3db4f6d2809da2f6"/><file name="cms_step5.phtml" hash="41503b9759aec987cde16389a1b7a7ac"/><file name="listing.phtml" hash="51403a39ad9e396656b9768e597af93d"/></dir><dir name="product"><dir name="attributes"><file name="edit.phtml" hash="5c2e06cb7b18b6cb34dd09398e0690cb"/></dir><dir name="category"><file name="edit.phtml" hash="acb8acba1981d3f764d120a62a4a70a7"/></dir><file name="edit.phtml" hash="fb6e94f86ba351d045d8516cc244577e"/><file name="index.phtml" hash="7ea9b53f06a8045e19d4727c41059d58"/></dir><dir name="tag"><dir name="tag"><file name="index.phtml" hash="d672d3415faa28fc85406e537b689b3c"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Transfluent_Translate.xml" hash="21fbc30a1cba6c2b86b262439eee8ed3"/></dir></target><target name="mageweb"><dir name="js"><dir name="transfluent"><file name="actions.js" hash="471135bf9f5941d0e22d11aa726bfc3b"/><file name="lib.js" hash="0f1029e5a4a1c1e88ca2bb8304bc34e8"/></dir></dir></target></contents>
26
  <compatible/>
27
+ <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php><extension><name>Core</name><min></min><max></max></extension><extension><name>curl</name><min></min><max></max></extension><extension><name>json</name><min></min><max></max></extension><extension><name>mbstring</name><min></min><max></max></extension></required></dependencies>
28
  </package>