Transfluent - Version 1.2.0

Version Notes

Added feature for translating whole categories in one order.

Download this release

Release Info

Developer Ilari Mäkimattila
Extension Transfluent
Version 1.2.0
Comparing to
See all releases


Version 1.2.0

Files changed (92) hide show
  1. app/code/community/Transfluent/Translate/Block/Account.php +19 -0
  2. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Grid.php +74 -0
  3. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Language.php +14 -0
  4. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/LanguagePair.php +17 -0
  5. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Level.php +14 -0
  6. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/SourceText.php +16 -0
  7. app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Store.php +13 -0
  8. app/code/community/Transfluent/Translate/Block/Adminhtml/Tag/Tag/Grid.php +70 -0
  9. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder.php +22 -0
  10. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit.php +20 -0
  11. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Form.php +97 -0
  12. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Tab/Form.php +75 -0
  13. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Tabs.php +24 -0
  14. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate.php +15 -0
  15. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit.php +25 -0
  16. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Form.php +20 -0
  17. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Tab/Form.php +125 -0
  18. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Tabs.php +23 -0
  19. app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Grid.php +87 -0
  20. app/code/community/Transfluent/Translate/Block/Estimate.php +15 -0
  21. app/code/community/Transfluent/Translate/Block/Help.php +15 -0
  22. app/code/community/Transfluent/Translate/Block/Loginform.php +21 -0
  23. app/code/community/Transfluent/Translate/Block/Regform.php +21 -0
  24. app/code/community/Transfluent/Translate/Block/Translblock.php +23 -0
  25. app/code/community/Transfluent/Translate/Exception/Base.php +28 -0
  26. app/code/community/Transfluent/Translate/Exception/EBackendCustomerHasNoBillingAgreement.php +10 -0
  27. app/code/community/Transfluent/Translate/Exception/EFailedToUpdateOrder.php +5 -0
  28. app/code/community/Transfluent/Translate/Exception/EInvalidInput.php +5 -0
  29. app/code/community/Transfluent/Translate/Exception/EInvalidJob.php +5 -0
  30. app/code/community/Transfluent/Translate/Exception/EInvalidTagFormat.php +10 -0
  31. app/code/community/Transfluent/Translate/Exception/ELanguagePairNotSupported.php +10 -0
  32. app/code/community/Transfluent/Translate/Exception/ETagNotFound.php +10 -0
  33. app/code/community/Transfluent/Translate/Exception/ETransfluentAuthenticationExpired.php +15 -0
  34. app/code/community/Transfluent/Translate/Exception/ETransfluentInvalidInputTags.php +10 -0
  35. app/code/community/Transfluent/Translate/Exception/ETransfluentNothingToTranslate.php +10 -0
  36. app/code/community/Transfluent/Translate/Exception/ETransfluentOrderFail.php +10 -0
  37. app/code/community/Transfluent/Translate/Exception/ETransfluentProductHasNoFieldsToTranslate.php +10 -0
  38. app/code/community/Transfluent/Translate/Exception/ETransfluentProductNotFound.php +10 -0
  39. app/code/community/Transfluent/Translate/Exception/ETransfluentSomeSelectedProductsNotFound.php +10 -0
  40. app/code/community/Transfluent/Translate/Exception/ETransfluentTagsNothingToTranslate.php +10 -0
  41. app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownBackendResponse.php +10 -0
  42. app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownError.php +10 -0
  43. app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownErrorNoEstimate.php +10 -0
  44. app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownErrorTags.php +10 -0
  45. app/code/community/Transfluent/Translate/Exception/EUnauthorized.php +5 -0
  46. app/code/community/Transfluent/Translate/Helper/Category.php +116 -0
  47. app/code/community/Transfluent/Translate/Helper/Constant.php +47 -0
  48. app/code/community/Transfluent/Translate/Helper/Data.php +41 -0
  49. app/code/community/Transfluent/Translate/Helper/Languages.php +394 -0
  50. app/code/community/Transfluent/Translate/Helper/Product.php +67 -0
  51. app/code/community/Transfluent/Translate/Helper/Tag.php +35 -0
  52. app/code/community/Transfluent/Translate/Helper/Text.php +27 -0
  53. app/code/community/Transfluent/Translate/Helper/Util.php +29 -0
  54. app/code/community/Transfluent/Translate/Model/AttributeName.php +46 -0
  55. app/code/community/Transfluent/Translate/Model/AttributeOption.php +34 -0
  56. app/code/community/Transfluent/Translate/Model/Base/Backendclient.php +308 -0
  57. app/code/community/Transfluent/Translate/Model/CategoryDetail.php +61 -0
  58. app/code/community/Transfluent/Translate/Model/Config/Source/Fromlang.php +19 -0
  59. app/code/community/Transfluent/Translate/Model/Config/Source/Language.php +21 -0
  60. app/code/community/Transfluent/Translate/Model/Config/Source/Quality.php +21 -0
  61. app/code/community/Transfluent/Translate/Model/Debugutil.php +68 -0
  62. app/code/community/Transfluent/Translate/Model/Mysql4/Transfluenttranslate.php +11 -0
  63. app/code/community/Transfluent/Translate/Model/Mysql4/Transfluenttranslate/Collection.php +11 -0
  64. app/code/community/Transfluent/Translate/Model/Observer.php +207 -0
  65. app/code/community/Transfluent/Translate/Model/ProductDetail.php +48 -0
  66. app/code/community/Transfluent/Translate/Model/TagName.php +47 -0
  67. app/code/community/Transfluent/Translate/Model/Transfluentorder.php +476 -0
  68. app/code/community/Transfluent/Translate/Model/Transfluenttranslate.php +197 -0
  69. app/code/community/Transfluent/Translate/controllers/Adminhtml/AccountController.php +35 -0
  70. app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluentorderController.php +433 -0
  71. app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluenttranslateController.php +532 -0
  72. app/code/community/Transfluent/Translate/controllers/TranslationController.php +328 -0
  73. app/code/community/Transfluent/Translate/etc/config.xml +155 -0
  74. app/code/community/Transfluent/Translate/etc/system.xml +151 -0
  75. app/code/community/Transfluent/Translate/sql/transfluenttranslate_setup/mysql4-install-1.1.0.php +31 -0
  76. app/design/adminhtml/default/default/layout/transfluent.xml +17 -0
  77. app/design/adminhtml/default/default/template/transfluent/account/action.phtml +23 -0
  78. app/design/adminhtml/default/default/template/transfluent/account/create.phtml +39 -0
  79. app/design/adminhtml/default/default/template/transfluent/account/logged.phtml +22 -0
  80. app/design/adminhtml/default/default/template/transfluent/account/login.phtml +36 -0
  81. app/design/adminhtml/default/default/template/transfluent/estimate.phtml +36 -0
  82. app/design/adminhtml/default/default/template/transfluent/estimate_section.phtml +99 -0
  83. app/design/adminhtml/default/default/template/transfluent/order/order.phtml +431 -0
  84. app/design/adminhtml/default/default/template/transfluent/product/attributes/edit.phtml +141 -0
  85. app/design/adminhtml/default/default/template/transfluent/product/category/edit.phtml +147 -0
  86. app/design/adminhtml/default/default/template/transfluent/product/edit.phtml +356 -0
  87. app/design/adminhtml/default/default/template/transfluent/product/index.phtml +190 -0
  88. app/design/adminhtml/default/default/template/transfluent/tag/tag/index.phtml +193 -0
  89. app/etc/modules/Transfluent_Translate.xml +9 -0
  90. js/transfluent/actions.js +249 -0
  91. js/transfluent/lib.js +68 -0
  92. package.xml +27 -0
app/code/community/Transfluent/Translate/Block/Account.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Account extends Mage_Core_Block_Template {
8
+ public function getToken() {
9
+ return Mage::getStoreConfig('transfluenttranslate/account/token');
10
+ }
11
+
12
+ public function getEmail() {
13
+ return Mage::getStoreConfig('transfluenttranslate/account/email');
14
+ }
15
+
16
+ public function getKey($action) {
17
+ return Mage::getSingleton('adminhtml/url')->getSecretKey("adminhtml_account", $action);
18
+ }
19
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Grid.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid {
8
+ protected function _prepareMassaction() {
9
+ parent::_prepareMassaction();
10
+
11
+ if (!Mage::getSingleton('admin/session')->isAllowed('catalog/update_attributes')){
12
+ return $this;
13
+ }
14
+ $store_id = $this->getRequest()->getParam('store');
15
+ if (!$store_id) {
16
+ return $this;
17
+ }
18
+
19
+ $stores = Mage::app()->getStores();
20
+ if (!$stores || count($stores) < 2) {
21
+ return $this;
22
+ }
23
+ $possible_source_stores = array();
24
+ foreach ($stores AS $store) {
25
+ /** @var Mage_Core_Model_Store $store */
26
+ if ($store_id == $store->getId()) {
27
+ continue;
28
+ }
29
+ $possible_source_stores[] = $store->getId();
30
+ }
31
+ if (empty($possible_source_stores)) {
32
+ return $this;
33
+ }
34
+ $email = Mage::getStoreConfig('transfluenttranslate/account/email');
35
+ if (is_null($email)) {
36
+ return $this;
37
+ }
38
+
39
+ $language_helper = Mage::helper('transfluenttranslate/languages');
40
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
41
+ $default_source_language_id = $language_helper->DefaultSourceLanguage($store_id);
42
+ $default_level = $language_helper->DefaultLevel();
43
+ $store_languages = $language_helper->getSourceLanguageArray($possible_source_stores, $default_source_language_id);
44
+ $quality = $language_helper->getQualityArray($default_level);
45
+
46
+ $this->getMassactionBlock()->addItem('translate', array(
47
+ 'label'=> Mage::helper('catalog')->__('Translate'),
48
+ 'url' => $this->getCurrentUrl(),
49
+ 'additional' => array(
50
+ 'visibility_lang' => array(
51
+ 'name' => 'translate_from',
52
+ 'type' => 'select',
53
+ 'class' => 'required-entry',
54
+ 'label' => Mage::helper('catalog')->__('from'),
55
+ 'values' => $store_languages
56
+ ),
57
+ 'visibility_quality' => array(
58
+ 'name' => 'level',
59
+ 'type' => 'select',
60
+ 'class' => 'required-entry',
61
+ 'label' => Mage::helper('catalog')->__('using'),
62
+ 'values' => $quality
63
+ ),
64
+ 'visibility_store' => array(
65
+ 'name' => 'translate_store',
66
+ 'type' => 'hidden',
67
+ 'class' => 'required-entry',
68
+ 'value' => $store_id
69
+ )
70
+ )
71
+ ));
72
+ return $this;
73
+ }
74
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Language.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_Language extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
8
+ public function render(Varien_Object $row) {
9
+ $value = $row->getData($this->getColumn()->getIndex());
10
+ $language_helper = Mage::helper('transfluenttranslate/languages');
11
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
12
+ return $language_helper->getLanguageNameByCode($language_helper->getLangById($value));
13
+ }
14
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/LanguagePair.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_LanguagePair extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
8
+ public function render(Varien_Object $row) {
9
+ $language_helper = Mage::helper('transfluenttranslate/languages');
10
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
11
+ $target_store_id = $row->getData($this->getColumn()->getIndex());
12
+ $source_store_id = $row->getData('source_store');
13
+ $target_language = $language_helper->getLanguageNameByCode($language_helper->GetStoreLocale($target_store_id), true);
14
+ $source_language = $language_helper->getLanguageNameByCode($language_helper->GetStoreLocale($source_store_id), true);
15
+ return $source_language . ' → ' . $target_language;
16
+ }
17
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Level.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_Level extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
8
+ public function render(Varien_Object $row) {
9
+ $value = $row->getData($this->getColumn()->getIndex());
10
+ $language_helper = Mage::helper('transfluenttranslate/languages');
11
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
12
+ return $language_helper->getQualityValue($value);
13
+ }
14
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/SourceText.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_SourceText extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
8
+ public function render(Varien_Object $row) {
9
+ $text_id = $row->getData($this->getColumn()->getIndex());
10
+ $model = Mage::helper('transfluenttranslate/text')->ModelByTextId($text_id);
11
+ if (!$model) {
12
+ return '[text id: ' . $text_id . ']';
13
+ }
14
+ return $model->OrderTitle();
15
+ }
16
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Catalog/Product/Renderer/Store.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_Store extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
8
+ public function render(Varien_Object $row) {
9
+ $value = $row->getData($this->getColumn()->getIndex());
10
+ $store = Mage::app()->getStore($value);
11
+ return $store->getName();
12
+ }
13
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Tag/Tag/Grid.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Tag_Tag_Grid extends Mage_Adminhtml_Block_Tag_Tag_Grid {
8
+ protected function _prepareMassaction() {
9
+ parent::_prepareMassaction();
10
+
11
+ if (!Mage::getSingleton('admin/session')->isAllowed('catalog/update_attributes')){
12
+ return $this;
13
+ }
14
+
15
+ $stores = Mage::app()->getStores();
16
+ if (!$stores || count($stores) < 2) {
17
+ return $this;
18
+ }
19
+ $helper = Mage::helper('transfluenttranslate/languages');
20
+ /** @var Transfluent_Translate_Helper_Languages $helper */
21
+ $possible_source_languages = array();
22
+ foreach ($stores AS $store) {
23
+ /** @var Mage_Core_Model_Store $store */
24
+ $possible_source_languages[] = $helper->GetStoreLocale($store->getCode());
25
+ }
26
+ if (empty($possible_source_languages)) {
27
+ return $this;
28
+ }
29
+ $email = Mage::getStoreConfig('transfluenttranslate/account/email');
30
+ if (is_null($email)) {
31
+ return $this;
32
+ }
33
+
34
+ $language_helper = Mage::helper('transfluenttranslate/languages');
35
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
36
+ $default_level = $language_helper->DefaultLevel();
37
+
38
+ $stores_and_languages = $language_helper->getSourceLanguageArrayForStores($stores);
39
+ $quality = $language_helper->getQualityArray($default_level);
40
+
41
+ $this->getMassactionBlock()->addItem('translate', array(
42
+ 'label'=> Mage::helper('catalog')->__('Translate'),
43
+ 'url' => $this->getUrl('*/*/', array('_current'=>true)),
44
+ 'additional' => array(
45
+ 'store_from' => array(
46
+ 'name' => 'store_from',
47
+ 'type' => 'select',
48
+ 'class' => 'required-entry',
49
+ 'label' => Mage::helper('catalog')->__('from'),
50
+ 'values' => $stores_and_languages
51
+ ),
52
+ 'store_to' => array(
53
+ 'name' => 'store_to',
54
+ 'type' => 'select',
55
+ 'class' => 'required-entry',
56
+ 'label' => Mage::helper('catalog')->__('to'),
57
+ 'values' => $stores_and_languages
58
+ ),
59
+ 'quality' => array(
60
+ 'name' => 'quality',
61
+ 'type' => 'select',
62
+ 'class' => 'required-entry',
63
+ 'label' => Mage::helper('catalog')->__('using'),
64
+ 'values' => $quality
65
+ )
66
+ )
67
+ ));
68
+ return $this;
69
+ }
70
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Block_Adminhtml_Transfluentorder
5
+ */
6
+ class Transfluent_Translate_Block_Adminhtml_Transfluentorder extends Mage_Adminhtml_Block_Widget_Form_Container {
7
+ public function __construct() {
8
+ $this->_controller = 'adminhtml_transfluentorder';
9
+ $this->_blockGroup = 'transfluenttranslate';
10
+ $this->_headerText = Mage::helper('transfluenttranslate')->__('Order new translation');
11
+
12
+ parent::__construct();
13
+ $this->removeButton('add');
14
+ $this->addButton('order_reorder', array(
15
+ 'label' => Mage::helper('sales')->__('Get Quote'),
16
+ 'onclick' => 'setLocation(\'' . $this->getUrl('transfluent/adminhtml_transfluentorder/getquote') . '\')',));
17
+
18
+ //$this->removeButton('save');
19
+ $this->_updateButton('save', 'label', 'Place order');
20
+ $this->_updateButton('save', 'disabled', true);
21
+ }
22
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit
5
+ */
6
+ class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit extends Mage_Adminhtml_Block_Widget_Form_Container {
7
+ public function __construct() {
8
+ parent::__construct();
9
+ $this->_objectId = 'id';
10
+ $this->_blockGroup = 'transfluentorder';
11
+ $this->_controller = 'adminhtml_transfluentorder';
12
+ $this->removeButton('save');
13
+ $this->removeButton('delete');
14
+ $this->removeButton('reset');
15
+ }
16
+
17
+ public function getHeaderText() {
18
+ return "blah";
19
+ }
20
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Form.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Block_Adminhtml_Transfluentorder_Edit_Form
5
+ */
6
+ class Transfluent_Translate_Block_Adminhtml_Transfluentorder_Edit_Form extends Mage_Adminhtml_Block_Widget_Form {
7
+
8
+ protected function _prepareForm() {
9
+ $form = new Varien_Data_Form(array(
10
+ 'id' => 'edit_form',
11
+ 'action' => $this->getUrl(
12
+ '*/*/save',
13
+ array('id' => $this->getRequest()->getParam('id'))),
14
+ 'method' => 'post',
15
+ )
16
+ );
17
+
18
+ $form->setUseContainer(true);
19
+ $this->setForm($form);
20
+
21
+ $stores = Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm();
22
+
23
+ // form
24
+ $fieldset = $form->addFieldset('orderForm', array(
25
+ 'legend' => Mage::helper('Core')->__('Translation info')
26
+ ));
27
+
28
+ // source language
29
+ $fieldset->addField('source', 'select', array(
30
+ 'label' => Mage::helper('Core')->__('Translate From'),
31
+ 'class' => 'required-entry',
32
+ 'required' => true,
33
+ 'name' => 'source',
34
+ 'note' => Mage::helper('Core')->__('Select source Store & Language'),
35
+ 'values' => $stores,
36
+ ));
37
+
38
+ // destination language
39
+ $fieldset->addField('destination', 'select', array(
40
+ 'label' => Mage::helper('Core')->__('To'),
41
+ 'class' => 'required-entry',
42
+ 'required' => true,
43
+ 'name' => 'destination',
44
+ 'note' => Mage::helper('Core')->__('Select destination Store & Language'),
45
+ 'values' => $stores
46
+ ));
47
+
48
+ // category list
49
+ $fieldset->addField('checkboxes', 'checkboxes', array(
50
+ 'label' => Mage::helper('Core')->__('Categories'),
51
+ 'name' => 'Checkbox',
52
+ 'required' => true,
53
+ 'values' => $this->getCategories(),
54
+ 'onclick' => "",
55
+ 'onchange' => "",
56
+ 'disabled' => false,
57
+ 'tabindex' => 4
58
+ ));
59
+
60
+ $fieldset->addField('submit', 'submit', array(
61
+ 'value' => 'Submit',
62
+ ));
63
+
64
+ $data = array();
65
+ $form->setValues($data);
66
+
67
+ $this->setForm($form);
68
+
69
+ return parent::_prepareForm();
70
+ }
71
+
72
+ /**
73
+ * get categories
74
+ *
75
+ * @return array
76
+ */
77
+ protected function getCategories() {
78
+
79
+ $category = Mage::getModel('catalog/category');
80
+ $tree = $category->getTreeModel();
81
+ $tree->load();
82
+ $ids = $tree->getCollection()->getAllIds();
83
+ $arr = array();
84
+ if (!empty($ids) && is_array($ids)) {
85
+ foreach ($ids as $id) {
86
+ $cat = Mage::getModel('catalog/category');
87
+ $cat->load($id);
88
+ if ($cat->getName() && $cat->getProductCount()) {
89
+ $catName = trim($cat->getName()) . ' (' . $cat->getProductCount() . ')';
90
+ $arr[] = array('value' => $id, 'label' => $catName);
91
+ }
92
+ }
93
+ }
94
+
95
+ return $arr;
96
+ }
97
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Tab/Form.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit_Tab_Form
5
+ */
6
+ class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form {
7
+ protected function _prepareForm() {
8
+ $form = new Varien_Data_Form();
9
+ $this->setForm($form);
10
+ $fieldset = $form->addFieldset(
11
+ 'transfluentorder_form',
12
+ array('legend' => Mage::helper('transfluenttranslate')->__('Order information'))
13
+ );
14
+
15
+ $fieldset->addField(
16
+ 'transfluentorder_textid',
17
+ 'text',
18
+ array(
19
+ 'label' => Mage::helper('transfluenttranslate')->__('Text ID'),
20
+ 'name' => 'transfluentorder_textid',
21
+ 'style' => "border: 0px; background: none;",
22
+ 'disabled' => true,
23
+ 'readonly' => true,
24
+ )
25
+ );
26
+
27
+ $fieldset->addField(
28
+ 'transfluentorder_quality',
29
+ 'text',
30
+ array(
31
+ 'label' => Mage::helper('transfluenttranslate')->__('Quality'),
32
+ 'text' => 'transfluentorder_quality',
33
+ 'style' => "border: 0px; background: none;",
34
+ 'disabled' => true,
35
+ 'readonly' => true,
36
+ )
37
+ );
38
+
39
+ $fieldset->addField(
40
+ 'transfluentorder_status',
41
+ 'select',
42
+ array(
43
+ 'label' => Mage::helper('transfluenttranslate')->__('Status'),
44
+ 'name' => 'transfluentorder_status',
45
+ 'class' => 'required-entry',
46
+ 'required' => true,
47
+ 'values' => array(
48
+ array(
49
+ 'value' => 1,
50
+ 'label' => Mage::helper('transfluenttranslate')->__('Queued'),
51
+ ),
52
+
53
+ array(
54
+ 'value' => 2,
55
+ 'label' => Mage::helper('transfluenttranslate')->__('Completed'),
56
+ ),
57
+
58
+ array(
59
+ 'value' => 3,
60
+ 'label' => Mage::helper('transfluenttranslate')->__('Canceled'),
61
+ ),
62
+ ),
63
+ )
64
+ );
65
+
66
+
67
+ if (Mage::getSingleton('adminhtml/session')->gettransfluentorderData()) {
68
+ $form->setValues(Mage::getSingleton('adminhtml/session')->gettransfluentorderData());
69
+ Mage::getSingleton('adminhtml/session')->settransfluentorderData(null);
70
+ } elseif (Mage::registry('transfluentorder_data')) {
71
+ $form->setValues(Mage::registry('transfluentorder_data')->getData());
72
+ }
73
+ return parent::_prepareForm();
74
+ }
75
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluentorder/Edit/Tabs.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit_Tabs
5
+ */
6
+ class Transfluent_Translate_Block_Adminhtml_transfluentorder_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
7
+ public function __construct() {
8
+ parent::__construct();
9
+ $this->setId('transfluentorder_tabs');
10
+ $this->setDestElementId('edit_form');
11
+ $this->setTitle(Mage::helper('transfluenttranslate')->__('Orders'));
12
+ }
13
+
14
+ protected function _beforeToHtml() {
15
+ $this->addTab('form_section', array(
16
+ 'label' => Mage::helper('transfluenttranslate')->__('View order details'),
17
+ 'title' => Mage::helper('transfluenttranslate')->__('View order details'),
18
+ 'content' => $this->getLayout()
19
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder_edit_tab_form')
20
+ ->toHtml(),
21
+ ));
22
+ return parent::_beforeToHtml();
23
+ }
24
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate extends Mage_Adminhtml_Block_Widget_Grid_Container {
8
+ public function __construct() {
9
+ $this->_controller = 'adminhtml_transfluenttranslate';
10
+ $this->_blockGroup = 'transfluenttranslate';
11
+ $this->_headerText = Mage::helper('transfluenttranslate')->__('Translation orders');
12
+ parent::__construct();
13
+ $this->removeButton('add');
14
+ }
15
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate_Edit extends Mage_Adminhtml_Block_Widget_Form_Container {
8
+ public function __construct() {
9
+ parent::__construct();
10
+ $this->_objectId = 'id';
11
+ $this->_blockGroup = 'transfluenttranslate';
12
+ $this->_controller = 'adminhtml_transfluenttranslate';
13
+ $this->removeButton('save');
14
+ $this->removeButton('delete');
15
+ $this->removeButton('reset');
16
+ }
17
+
18
+ public function getHeaderText() {
19
+ if(Mage::registry('transfluenttranslate_data') && Mage::registry('transfluenttranslate_data')->getId()) {
20
+ return Mage::helper('transfluenttranslate')->__("View order for text: '%s'", $this->htmlEscape(Mage::registry('transfluenttranslate_data')->getTransfluenttranslateTextid()));
21
+ } else {
22
+ return Mage::helper('transfluenttranslate')->__('N/A');
23
+ }
24
+ }
25
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Form.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate_Edit_Form extends Mage_Adminhtml_Block_Widget_Form {
8
+ protected function _prepareForm() {
9
+ $form = new Varien_Data_Form(array(
10
+ 'id' => 'edit_form',
11
+ 'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
12
+ 'method' => 'post',
13
+ )
14
+ );
15
+ $form->setUseContainer(true);
16
+ $this->setForm($form);
17
+
18
+ return parent::_prepareForm();
19
+ }
20
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Tab/Form.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form {
8
+ protected function _prepareForm() {
9
+ $form = new Varien_Data_Form();
10
+ $this->setForm($form);
11
+ $fieldset = $form->addFieldset(
12
+ 'transfluenttranslate_form',
13
+ array(
14
+ 'legend' => Mage::helper('transfluenttranslate')->__('Order information')
15
+ )
16
+ );
17
+
18
+ $fieldset->addField(
19
+ 'transfluenttranslate_textid',
20
+ 'text',
21
+ array(
22
+ 'label' => Mage::helper('transfluenttranslate')->__('Text ID'),
23
+ 'name' => 'transfluenttranslate_textid',
24
+ 'style' => "border: 0px; background: none;",
25
+ 'disabled' => true,
26
+ 'readonly' => true,
27
+ )
28
+ );
29
+
30
+ $fieldset->addField(
31
+ 'transfluenttranslate_product',
32
+ 'text',
33
+ array(
34
+ 'label' => Mage::helper('transfluenttranslate')->__('Product'),
35
+ 'name' => 'transfluenttranslate_product',
36
+ 'style' => "border: 0px; background: none;",
37
+ 'disabled' => true,
38
+ 'readonly' => true,
39
+ )
40
+ );
41
+
42
+ $fieldset->addField(
43
+ 'transfluenttranslate_store',
44
+ 'text',
45
+ array(
46
+ 'label' => Mage::helper('transfluenttranslate')->__('Store'),
47
+ 'name' => 'transfluenttranslate_store',
48
+ 'style' => "border: 0px; background: none;",
49
+ 'disabled' => true,
50
+ 'readonly' => true,
51
+ )
52
+ );
53
+
54
+ $fieldset->addField(
55
+ 'transfluenttranslate_sourcelang',
56
+ 'text',
57
+ array(
58
+ 'label' => Mage::helper('transfluenttranslate')->__('Source language'),
59
+ 'name' => 'transfluenttranslate_sourcelang',
60
+ 'style' => "border: 0px; background: none;",
61
+ 'disabled' => true,
62
+ 'readonly' => true,
63
+ )
64
+ );
65
+
66
+ $fieldset->addField(
67
+ 'transfluenttranslate_targetlang',
68
+ 'text',
69
+ array(
70
+ 'label' => Mage::helper('transfluenttranslate')->__('Target language'),
71
+ 'name' => 'transfluenttranslate_targetlang',
72
+ 'style' => "border: 0px; background: none;",
73
+ 'disabled' => true,
74
+ 'readonly' => true,
75
+ )
76
+ );
77
+
78
+ $fieldset->addField(
79
+ 'transfluenttranslate_quality',
80
+ 'text',
81
+ array(
82
+ 'label' => Mage::helper('transfluenttranslate')->__('Quality'),
83
+ 'text' => 'transfluenttranslate_quality',
84
+ 'style' => "border: 0px; background: none;",
85
+ 'disabled' => true,
86
+ 'readonly' => true,
87
+ )
88
+ );
89
+
90
+ $fieldset->addField(
91
+ 'transfluenttranslate_status',
92
+ 'select',
93
+ array(
94
+ 'label' => Mage::helper('transfluenttranslate')->__('Status'),
95
+ 'name' => 'transfluenttranslate_status',
96
+ 'class' => 'required-entry',
97
+ 'required' => true,
98
+ 'values' => array(
99
+ array(
100
+ 'value' => 1,
101
+ 'label' => Mage::helper('transfluenttranslate')->__('Queued'),
102
+ ),
103
+
104
+ array(
105
+ 'value' => 2,
106
+ 'label' => Mage::helper('transfluenttranslate')->__('Completed'),
107
+ ),
108
+
109
+ array(
110
+ 'value' => 3,
111
+ 'label' => Mage::helper('transfluenttranslate')->__('Canceled'),
112
+ ),
113
+ ),
114
+ )
115
+ );
116
+
117
+ if (Mage::getSingleton('adminhtml/session')->getTransfluenttranslateData()) {
118
+ $form->setValues(Mage::getSingleton('adminhtml/session')->getTransfluenttranslateData());
119
+ Mage::getSingleton('adminhtml/session')->setTransfluenttranslateData(null);
120
+ } elseif (Mage::registry('transfluenttranslate_data')) {
121
+ $form->setValues(Mage::registry('transfluenttranslate_data')->getData());
122
+ }
123
+ return parent::_prepareForm();
124
+ }
125
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Edit/Tabs.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
8
+ public function __construct() {
9
+ parent::__construct();
10
+ $this->setId('transfluenttranslate_tabs');
11
+ $this->setDestElementId('edit_form');
12
+ $this->setTitle(Mage::helper('transfluenttranslate')->__('Orders'));
13
+ }
14
+
15
+ protected function _beforeToHtml() {
16
+ $this->addTab('form_section', array(
17
+ 'label' => Mage::helper('transfluenttranslate')->__('View order details'),
18
+ 'title' => Mage::helper('transfluenttranslate')->__('View order details'),
19
+ 'content' => $this->getLayout()->createBlock('transfluenttranslate/adminhtml_transfluenttranslate_edit_tab_form')->toHtml(),
20
+ ));
21
+ return parent::_beforeToHtml();
22
+ }
23
+ }
app/code/community/Transfluent/Translate/Block/Adminhtml/Transfluenttranslate/Grid.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Adminhtml_Transfluenttranslate_Grid extends Mage_Adminhtml_Block_Widget_Grid {
8
+ public function __construct() {
9
+ parent::__construct();
10
+ $this->setId('translations_grid');
11
+ $this->setDefaultSort('id');
12
+ $this->setDefaultDir('DESC');
13
+ $this->setSaveParametersInSession(true);
14
+ $this->setUseAjax(true);
15
+ }
16
+
17
+ protected function _prepareCollection() {
18
+ $collection = Mage::getModel('transfluenttranslate/transfluenttranslate')->getCollection();
19
+ $this->setCollection($collection);
20
+ return parent::_prepareCollection();
21
+ }
22
+
23
+ protected function _prepareColumns() {
24
+ $this->addColumn('id', array(
25
+ 'header' => Mage::helper('transfluenttranslate')->__('ID'),
26
+ 'align' => 'right',
27
+ 'width' => '50px',
28
+ 'index' => 'id',
29
+ ));
30
+
31
+ $this->addColumn('source_text', array(
32
+ 'header' => Mage::helper('transfluenttranslate')->__('Text'),
33
+ 'align' => 'left',
34
+ 'width' => '150px',
35
+ 'index' => 'text_id',
36
+ 'renderer' => 'Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_SourceText',
37
+ ));
38
+
39
+ $this->addColumn('target_store', array(
40
+ 'header' => Mage::helper('transfluenttranslate')->__('Target store'),
41
+ 'align' => 'left',
42
+ 'width' => '150px',
43
+ 'index' => 'target_store',
44
+ 'renderer' => 'Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_Store',
45
+ ));
46
+
47
+ $this->addColumn('language_pair', array(
48
+ 'header' => Mage::helper('transfluenttranslate')->__('Language pair'),
49
+ 'align' => 'left',
50
+ 'width' => '150px',
51
+ 'index' => 'target_store',
52
+ 'renderer' => 'Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_LanguagePair',
53
+ ));
54
+
55
+ $this->addColumn('level', array(
56
+ 'header' => Mage::helper('transfluenttranslate')->__('Level'),
57
+ 'align' => 'left',
58
+ 'width' => '150px',
59
+ 'index' => 'level',
60
+ 'renderer' => 'Transfluent_Translate_Block_Adminhtml_Catalog_Product_Renderer_Level',
61
+ ));
62
+
63
+ $this->addColumn('status', array(
64
+ 'header' => Mage::helper('transfluenttranslate')->__('Status'),
65
+ 'align' => 'left',
66
+ 'width' => '80px',
67
+ 'index' => 'status',
68
+ 'type' => 'options',
69
+ 'options' => array(
70
+ 1 => 'Queued',
71
+ 2 => 'Completed',
72
+ 3 => 'Canceled'
73
+ ),
74
+ ));
75
+
76
+ return parent::_prepareColumns();
77
+ }
78
+
79
+ public function getRowUrl($row) {
80
+ return null; // @todo: Disabled
81
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
82
+ }
83
+
84
+ public function getGridUrl() {
85
+ return $this->getUrl('*/*/grid', array('_current' => true));
86
+ }
87
+ }
app/code/community/Transfluent/Translate/Block/Estimate.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Estimate extends Mage_Adminhtml_Block_System_Config_Form_Field {
8
+ public function getEstimate() {
9
+ return Mage::getSingleton('admin/session')->getEstimate();
10
+ }
11
+
12
+ public function clearEstimate() {
13
+ return Mage::getSingleton('admin/session')->unsEstimate();
14
+ }
15
+ }
app/code/community/Transfluent/Translate/Block/Help.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Help extends Mage_Adminhtml_Block_System_Config_Form_Field {
8
+ public function render(Varien_Data_Form_Element_Abstract $element) {
9
+ return '';
10
+ }
11
+
12
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
13
+ return '';
14
+ }
15
+ }
app/code/community/Transfluent/Translate/Block/Loginform.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Loginform extends Mage_Adminhtml_Block_System_Config_Form_Field {
8
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {}
9
+
10
+ public function render(Varien_Data_Form_Element_Abstract $element) {
11
+ $token = Mage::getStoreConfig('transfluenttranslate/account/token');
12
+ if ($token != '') {
13
+ $html = $this->getLayout()->createBlock('transfluenttranslate/account')->setTemplate('transfluent/account/logged.phtml')->toHtml();
14
+ } else {
15
+ $html = $this->getLayout()->createBlock('transfluenttranslate/account')->setTemplate('transfluent/account/login.phtml')->toHtml();
16
+ }
17
+ $html .= $this->getLayout()->createBlock('transfluenttranslate/account')->setTemplate('transfluent/account/action.phtml')->toHtml();
18
+ $res = '<td>' . $html . '</td>';
19
+ return $this->_decorateRowHtml($element, $res);
20
+ }
21
+ }
app/code/community/Transfluent/Translate/Block/Regform.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Regform extends Mage_Adminhtml_Block_System_Config_Form_Field {
8
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {}
9
+
10
+ public function render(Varien_Data_Form_Element_Abstract $element) {
11
+ $token = Mage::getStoreConfig('transfluenttranslate/account/token');
12
+ if ($token != '') {
13
+ $html = $this->__('You have successfully connected to Transfluent.com');
14
+ } else {
15
+ $html = $this->getLayout()->createBlock('transfluenttranslate/account')->setTemplate('transfluent/account/create.phtml')->toHtml();
16
+ }
17
+ $res = '<td>' . $html . '</td>';
18
+
19
+ return $this->_decorateRowHtml($element, $res);
20
+ }
21
+ }
app/code/community/Transfluent/Translate/Block/Translblock.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Block_Translblock extends Mage_Adminhtml_Block_System_Config_Form_Field {
8
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
9
+ }
10
+
11
+ public function render(Varien_Data_Form_Element_Abstract $element) {
12
+ $token = Mage::getStoreConfig('transfluenttranslate/account/token');
13
+ if ($token != '') {
14
+ $html = $this->getLayout()->createBlock('transfluenttranslate/estimate')->setTemplate('transfluent/estimate_section.phtml')->toHtml();
15
+ } else {
16
+ $html = '<div class="notification-global">' . $this->__('Please finish Transfluent extension configuration first.') . '</div>';
17
+ }
18
+
19
+ $res = '<td>' . $html . '</td>';
20
+
21
+ return $this->_decorateRowHtml($element, $res);
22
+ }
23
+ }
app/code/community/Transfluent/Translate/Exception/Base.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Transfluent_Translate_Exception_Base extends Exception {
4
+ protected $_message = 'An unknown error occured';
5
+
6
+ public function __construct() {
7
+ $arguments = func_get_args();
8
+
9
+ $message = Mage::helper('Core')->__($this->_message);
10
+ parent::__construct(sprintf($message, $arguments), 1023);
11
+ }
12
+
13
+ /**
14
+ * Create a new exception from our backend error messages.
15
+ *
16
+ * @param $name
17
+ * @return Transfluent_Translate_Exception_Base
18
+ */
19
+ public static function create($name) {
20
+ $name = 'Transfluent_Translate_Exception_' . str_replace('Exception', '', $name);
21
+ try {
22
+ return new $name();
23
+ } catch (Exception $e) {
24
+ return null;
25
+ }
26
+ }
27
+
28
+ }
app/code/community/Transfluent/Translate/Exception/EBackendCustomerHasNoBillingAgreement.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_EBackendCustomerHasNoBillingAgreement
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_EBackendCustomerHasNoBillingAgreement extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Order was refused because your account is not in billing mode. Please contact sales@transfluent.com to sort out invoicing.';
10
+ }
app/code/community/Transfluent/Translate/Exception/EFailedToUpdateOrder.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Transfluent_Translate_Exception_EFailedToUpdateOrder extends Transfluent_Translate_Exception_Base {
4
+ protected $_message = 'Failed to update associated order data in Magento DB';
5
+ }
app/code/community/Transfluent/Translate/Exception/EInvalidInput.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Transfluent_Translate_Exception_EInvalidInput extends Transfluent_Translate_Exception_Base {
4
+ protected $_message = 'Input is not readable';
5
+ }
app/code/community/Transfluent/Translate/Exception/EInvalidJob.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Transfluent_Translate_Exception_EInvalidJob extends Transfluent_Translate_Exception_Base {
4
+ protected $_message = 'Invalid job id';
5
+ }
app/code/community/Transfluent/Translate/Exception/EInvalidTagFormat.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_EInvalidTagFormat
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_EInvalidTagFormat extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Invalid Input tags format!';
10
+ }
app/code/community/Transfluent/Translate/Exception/ELanguagePairNotSupported.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ELanguagePairNotSupported
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ELanguagePairNotSupported extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Requested language pair is unfortunately not supported on selected translator level. Please try different translator level or another language pair.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETagNotFound.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETagNotFound
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETagNotFound extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Unfortunately selected tags were not found or you did not select any!';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentAuthenticationExpired.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentAuthenticationExpired
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = "Your Transfluent.com authentication has expired. Please perform re-authentication in <a href='%s'>Configuration</a>-section.</div>";
10
+
11
+ public function __construct() {
12
+ parent::__construct(Mage::helper("adminhtml")
13
+ ->getUrl("adminhtml/system_config/edit/section/transfluenttranslate/"));
14
+ }
15
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentInvalidInputTags.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentInvalidInputTags
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentInvalidInputTagsBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = "Input tags' format is invalid!";
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentNothingToTranslate.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentNothingToTranslate
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'The translation request was rejected because the product details either contained nothing to translate or the details have been already translated.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentOrderFail.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentOrderFail
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentOrderFailBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Translation order was unsuccessful for at least one product.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentProductHasNoFieldsToTranslate.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslate
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Product details are already translated! You can force a translation request by setting "Use default value" option on to name, description and short description fields and saving product details before trying again.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentProductNotFound.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentProductNotFound
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentProductNotFoundBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Product was not found.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentSomeSelectedProductsNotFound.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentSomeSelectedProductsNotFound
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentSomeSelectedProductsNotFoundBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Some of the selected products were not found!';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentTagsNothingToTranslate.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentTagsNothingToTranslate
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentTagsNothingToTranslateBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'The translation request was rejected because the tags either contained nothing to translate or they have been already translated.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownBackendResponse.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentUnknownBackendResponse
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentUnknownBackendResponseBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Failed to serve your request. Please try again.!';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownError.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentUnknownError
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentUnknownErrorBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Failed to save product texts. Order was not placed, please try again! If problem persists, please contact support@transfluent.com.';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownErrorNoEstimate.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentUnknownErrorNoEstimate
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentUnknownErrorNoEstimateBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'An error occurred and costs could not be estimated at the moment. Please try again!';
10
+ }
app/code/community/Transfluent/Translate/Exception/ETransfluentUnknownErrorTags.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Exception_ETransfluentUnknownErrorTags
5
+ *
6
+ */
7
+ class Transfluent_Translate_Exception_ETransfluentUnknownErrorTagsBase extends Transfluent_Translate_Exception_Base
8
+ {
9
+ protected $_message = 'Failed to save tags to our system. Order was not placed, please try again! If problem persists, please contact support@transfluent.com.';
10
+ }
app/code/community/Transfluent/Translate/Exception/EUnauthorized.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Transfluent_Translate_Exception_EUnauthorized extends Transfluent_Translate_Exception_Base {
4
+ protected $_message = 'Access denied';
5
+ }
app/code/community/Transfluent/Translate/Helper/Category.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Helper_Category
5
+ */
6
+ class Transfluent_Translate_Helper_Category extends Mage_Core_Helper_Abstract {
7
+
8
+ /**
9
+ * get categories
10
+ *
11
+ * @return array
12
+ */
13
+ public function getCategoryArray() {
14
+ $category = Mage::getModel('catalog/category');
15
+ $tree = $category->getTreeModel();
16
+ $tree->load();
17
+ $ids = $tree->getCollection()->getAllIds();
18
+
19
+ $arr = $this->categoriesToArray($ids);
20
+ return $arr;
21
+ }
22
+
23
+ private function categoriesToArray($ids, &$visited = array()) {
24
+ $arr = array();
25
+ if (!empty($ids) && is_array($ids)) {
26
+ foreach ($ids as $id) {
27
+ $ret = $this->categoryToArray($id, $visited);
28
+ if ($ret !== null)
29
+ $arr[] = $ret;
30
+ }
31
+ }
32
+ return $arr;
33
+ }
34
+
35
+ private function categoryToArray($id, &$visited) {
36
+ if (in_array($id, $visited)) return null;
37
+
38
+ $visited[] = $id;
39
+
40
+ $arr = null;
41
+ /** @var Mage_Catalog_Model_Category $cat */
42
+ $cat = Mage::getModel('catalog/category');
43
+ $cat->load($id);
44
+ if ($cat->getName() && $cat->getProductCount()) {
45
+ $arr = array(
46
+ 'value' => $id,
47
+ 'label' => $cat->getName(),
48
+ 'productCount' => $cat->getProductCount(),
49
+ 'children' => $this->categoriesToArray($cat->getAllChildren(true), $visited)
50
+ );
51
+ }
52
+ return $arr;
53
+ }
54
+
55
+ /**
56
+ * gets all the productIDs from all the categories
57
+ *
58
+ * @return string
59
+ */
60
+ public function getCategoryProducts() {
61
+ $category = Mage::getModel('catalog/category');
62
+ $tree = $category->getTreeModel();
63
+ $tree->load();
64
+ $ids = $tree->getCollection()->getAllIds();
65
+ $products = array();
66
+
67
+ $categoryData = null;
68
+ foreach ($ids as $id) {
69
+ $category = Mage::getModel('catalog/category')->load(intval($id));
70
+
71
+ if ($category->getName() && $category->getProductCount()) {
72
+ foreach ($category->getProductCollection() as $product) {
73
+ $product = Mage::getModel('catalog/product')->load($product->getId());
74
+ $products[$id][] = $product->getId();
75
+ }
76
+ }
77
+ }
78
+
79
+
80
+ return json_encode($products);
81
+ }
82
+
83
+
84
+ /**
85
+ * get checkbox html of categories
86
+ *
87
+ * @return string
88
+ */
89
+ public function getCategoriesHTML() {
90
+ $categories = $this->getCategoryArray();
91
+ $html = $this->categoryArrayToHtml($categories);
92
+ return $html;
93
+ }
94
+
95
+ /**
96
+ * @param $categories
97
+ * @return string
98
+ */
99
+ private function categoryArrayToHtml($categories) {
100
+ $html = "<ul style=\"margin-left: 15px\">";
101
+ foreach ($categories as $category) {
102
+ $html .= "<li>";
103
+ $html .= "<input type='checkbox' name='chk_group[]' value=" . $category['value'] . " /> " . $category['label']
104
+ . " (" . $category['productCount'] . ")" . "<br/>";
105
+
106
+ if ($category['children']) {
107
+ $html .= $this->categoryArrayToHtml($category['children']);
108
+ }
109
+
110
+ $html .= "</li>";
111
+ }
112
+
113
+ $html .= "</ul>";
114
+ return $html;
115
+ }
116
+ }
app/code/community/Transfluent/Translate/Helper/Constant.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Helper_Constants
5
+ */
6
+ class Transfluent_Translate_Helper_Constant extends Mage_Core_Helper_Abstract {
7
+
8
+ /**
9
+ * returns non-translatable attributes
10
+ *
11
+ * @return array
12
+ */
13
+ public function getNonTranslatableAttributes() {
14
+ return array(
15
+ 'weight',
16
+ 'status',
17
+ 'tax_class_id',
18
+ 'visibility',
19
+ 'news_from_date',
20
+ 'news_to_date',
21
+ 'price',
22
+ 'group_price',
23
+ 'cost',
24
+ 'tier_price',
25
+ 'special_price',
26
+ 'special_from_date',
27
+ 'special_to_date',
28
+ 'enable_googlecheckout',
29
+ 'msrp_enabled',
30
+ 'msrp_display_actual_price_type',
31
+ 'msrp',
32
+ 'thumbnail',
33
+ 'small_image',
34
+ 'image',
35
+ 'gallery',
36
+ 'media_gallery',
37
+ 'custom_design_from',
38
+ 'custom_design_to',
39
+ 'custom_layout_update',
40
+ 'options_container',
41
+ 'page_layout',
42
+ 'is_recurring',
43
+ 'recurring_profile',
44
+ 'gift_message_available',
45
+ );
46
+ }
47
+ }
app/code/community/Transfluent/Translate/Helper/Data.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Helper_Data extends Mage_Core_Helper_Abstract {
8
+ public function getFields($sku) {
9
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
10
+ $setId = $product->getAttributeSetId();
11
+ $attributes = Mage::getModel('catalog/product_attribute_api')->items($setId);
12
+ $fields = array();
13
+ foreach ($attributes AS $attr) {
14
+ $attrId = $attr['attribute_id'];
15
+ $attribute = Mage::getModel('eav/entity_attribute')->load($attrId);
16
+ if ($attribute['is_visible_on_front'] == 1) {
17
+ $fields[] = $attribute['attribute_code'];
18
+ }
19
+ }
20
+ return $fields;
21
+ }
22
+
23
+ public function getProductEdit() {
24
+ $action = Mage::app()->getRequest()->getActionName();
25
+ if ($action == 'edit') {
26
+ return true;
27
+ }
28
+ return false;
29
+ }
30
+
31
+ public function getStoreByCode($storeCode) {
32
+ $storeId = 0;
33
+ $stores = Mage::getModel('core/store')->getCollection()->getData();
34
+ foreach ($stores as $store) {
35
+ if ($store['code'] == $storeCode) {
36
+ $storeId = $store['store_id'];
37
+ }
38
+ }
39
+ return $storeId;
40
+ }
41
+ }
app/code/community/Transfluent/Translate/Helper/Languages.php ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Helper_Languages extends Mage_Core_Helper_Abstract {
8
+ public function getTransfluentLangs() {
9
+ $languages_json = <<<EOFJSON
10
+ {"status":"OK","response":[{"1":{"name":"English","code":"en-gb","id":1}},{"2":{"name":"French","code":"fr-fr","id":2}},{"3":{"name":"German","code":"de-de","id":3}},{"4":{"name":"Chinese (Mandarin, Simplified)","code":"zh-cn","id":4}},{"5":{"name":"Chinese","code":"zh-hk","id":5}},{"6":{"name":"Spanish","code":"es-es","id":6}},{"7":{"name":"Japanese","code":"ja-jp","id":7}},{"8":{"name":"Korean","code":"ko-kr","id":8}},{"9":{"name":"Tagalog (Philippines)","code":"tl-ph","id":9}},{"10":{"name":"Portuguese","code":"pt-br","id":10}},{"11":{"name":"Finnish","code":"fi-fi","id":11}},{"12":{"name":"Italian","code":"it-it","id":12}},{"13":{"name":"Dutch","code":"nl-nl","id":13}},{"14":{"name":"Swedish","code":"sv-se","id":14}},{"15":{"name":"Russian","code":"ru-ru","id":15}},{"16":{"name":"Hindi","code":"hi-in","id":16}},{"17":{"name":"Arabic","code":"ar-sa","id":17}},{"18":{"name":"Malay","code":"ms-my","id":18}},{"19":{"name":"Romanian","code":"ro-ro","id":19}},{"20":{"name":"Lithuanian","code":"lt-lt","id":20}},{"21":{"name":"Hebrew","code":"he-il","id":21}},{"22":{"name":"Danish","code":"da-dk","id":22}},{"23":{"name":"Vietnamese","code":"vi-vn","id":23}},{"24":{"name":"Polish","code":"pl-pl","id":24}},{"25":{"name":"Turkish","code":"tr-tr","id":25}},{"26":{"name":"Thai","code":"th-th","id":26}},{"27":{"name":"Norwegian","code":"no-no","id":27}},{"28":{"name":"Ukrainian","code":"uk-ua","id":28}},{"29":{"name":"Hungarian","code":"hu-hu","id":29}},{"30":{"name":"Greek","code":"el-gr","id":30}},{"31":{"name":"Czech","code":"cs-cz","id":31}},{"32":{"name":"Catalan","code":"ca-ad","id":32}},{"33":{"name":"Esperanto","code":"eo-eo","id":33}},{"34":{"name":"Bengali","code":"bn-bd","id":34}},{"35":{"name":"Urdu","code":"ur-pk","id":35}},{"36":{"name":"Latin","code":"la-it","id":36}},{"37":{"name":"Persian","code":"fa-ir","id":37}},{"38":{"name":"Slovak","code":"sk-sk","id":38}},{"39":{"name":"Bulgarian","code":"bg-bg","id":39}},{"40":{"name":"Estonian","code":"et-ee","id":40}},{"41":{"name":"Latvian","code":"lv-lv","id":41}},{"42":{"name":"Somali","code":"so-so","id":42}},{"43":{"name":"Serbian","code":"sr-rs","id":43}},{"44":{"name":"Croatian","code":"hr-hr","id":44}},{"45":{"name":"Albanian","code":"sq-al","id":45}},{"46":{"name":"Azerbaijani","code":"az-az","id":46}},{"47":{"name":"Tamil","code":"ta-in","id":47}},{"48":{"name":"Swahili","code":"sw-ke","id":48}},{"49":{"name":"Macedonian","code":"mk-mk","id":49}},{"50":{"name":"Tibetan","code":"bo-cn","id":50}},{"51":{"name":"Punjabi","code":"pa-in","id":51}},{"52":{"name":"Javanese","code":"jv-id","id":52}},{"53":{"name":"Armenian","code":"hy-am","id":53}},{"54":{"name":"Basque","code":"eu-es","id":54}},{"55":{"name":"Kyrgyz","code":"ky-kg","id":55}},{"56":{"name":"Chinese (Traditional)","code":"zh-tw","id":56}},{"57":{"name":"Amharic","code":"am-et","id":57}},{"58":{"name":"Akan-Twi","code":"tw-gh","id":58}},{"59":{"name":"Hausa","code":"ha-ng","id":59}},{"60":{"name":"Igbo","code":"ig-ng","id":60}},{"61":{"name":"Slovenian","code":"sl-si","id":61}},{"128":{"name":"Indonesian","code":"id-id","id":128}},{"129":{"name":"Portuguese","code":"pt-pt","id":129}},{"130":{"name":"Afrikaans","code":"af-za","id":130}},{"131":{"name":"Bosnian","code":"bs-ba","id":131}},{"132":{"name":"Georgian","code":"ka-ge","id":132}},{"133":{"name":"Kazakh","code":"kk-kz","id":133}},{"134":{"name":"Central Khmer","code":"km-kh","id":134}},{"135":{"name":"Lao","code":"lo-la","id":135}},{"136":{"name":"Pashto","code":"ps-af","id":136}},{"137":{"name":"Uzbek","code":"uz-uz","id":137}},{"138":{"name":"Mongolian","code":"mn-mn","id":138}},{"139":{"name":"Nepali","code":"ne-np","id":139}},{"140":{"name":"Welsh","code":"cy-gb","id":140}},{"141":{"name":"Icelandic","code":"is-is","id":141}},{"142":{"name":"Taiwan Chinese","code":"zh-sg","id":142}},{"143":{"name":"Tigrinya","code":"ti-bo","id":143}},{"144":{"name":"Spanish","code":"es-la","id":144}},{"145":{"name":"French","code":"fr-ca","id":145}},{"146":{"name":"English","code":"en-ca","id":146}},{"147":{"name":"English","code":"en-sg","id":147}},{"148":{"name":"English","code":"en-us","id":148}},{"149":{"name":"Spanish","code":"es-cl","id":149}},{"150":{"name":"Spanish","code":"es-co","id":150}},{"151":{"name":"Spanish","code":"es-mx","id":151}},{"152":{"name":"Spanish","code":"es-ve","id":152}},{"500":{"name":"Pseudo language","code":"xx-xx","id":500}}]}
11
+ EOFJSON;
12
+ return Mage::helper('core')->jsonDecode($languages_json);
13
+ }
14
+
15
+ public function getLanguages() {
16
+ $languages = $this->getTransfluentLangs();
17
+ $langs = array();
18
+
19
+ foreach ($languages['response'] as $lang) {
20
+ foreach ($lang as $_lang) {
21
+ $langs[] = $_lang;
22
+ }
23
+ }
24
+
25
+ return $langs;
26
+ }
27
+
28
+ public function DefaultLevel() {
29
+ return Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_quality');
30
+ }
31
+
32
+ public function SetDefaultLevel($level) {
33
+ try {
34
+ $coreConfig = Mage::getModel('core/config');
35
+ $coreConfig->saveConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_quality', $level);
36
+ Mage::getConfig()->reinit();
37
+ Mage::app()->reinitStores();
38
+ } catch (Exception $e) {
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+
44
+ public function DefaultSourceLanguage($store_id = 0) {
45
+ return Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language', $store_id);
46
+ }
47
+
48
+ public function SetDefaultSourceLanguage($language_id) {
49
+ try {
50
+ $coreConfig = Mage::getModel('core/config');
51
+ $coreConfig->saveConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language', $language_id);
52
+ Mage::getConfig()->reinit();
53
+ Mage::app()->reinitStores();
54
+ } catch (Exception $e) {
55
+ return false;
56
+ }
57
+ return true;
58
+ }
59
+
60
+ public function getSourceLanguages() {
61
+ $stores = Mage::app()->getStores();
62
+ if (!$stores || count($stores) < 2) {
63
+ return array();
64
+ }
65
+ $helper = Mage::helper('transfluenttranslate/languages');
66
+ /** @var Transfluent_Translate_Helper_Languages $helper */
67
+ $source_languages = array();
68
+ $current_store = Mage::app()->getStore(true);
69
+ foreach ($stores AS $store) {
70
+ /** @var Mage_Core_Model_Store $store */
71
+ if ($current_store && $current_store->getCode() == $store->getCode()) {
72
+ continue;
73
+ }
74
+ $source_languages[] = $helper->GetStoreLocale($store->getCode());
75
+ }
76
+ return $source_languages;
77
+ }
78
+
79
+ public function getSourceLanguageSelectHtmlForStores($stores) {
80
+ $default_source_language_id = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language');
81
+ $html = '<select id="translateto" class="translateto_select">';
82
+ foreach ($stores AS $store) {
83
+ /** @var Mage_Core_Model_Store $store */
84
+ $store_language = $this->GetStoreLocale($store->getCode());
85
+ $language_id = $this->getLangByCode($store_language, true);
86
+ if (is_null($language_id)) {
87
+ // Language is unsupported
88
+ continue;
89
+ }
90
+ $is_selected = ($default_source_language_id == $language_id);
91
+ $html .= '<option value="' . $store->getId() . '"' . ($is_selected ? ' selected="SELECTED"' : '') . '>' . $this->getLanguageNameByCode($store_language, true) . ' (' . $store->getName() . ')</option>';
92
+ }
93
+ $html .= '</select>';
94
+ return $html;
95
+ }
96
+
97
+ public function getSourceLanguageSelectHtml($stores) {
98
+ $default_source_language_id = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language');
99
+ $html = '<select id="store_language" class="translateto_select">';
100
+ foreach ($stores AS $store_id) {
101
+ $store = Mage::app()->getStore($store_id);
102
+ $language_code = $this->GetStoreLocale($store_id);
103
+ $language_id = $this->getLangByCode($language_code, true);
104
+ if (is_null($language_id)) {
105
+ // Language is unsupported
106
+ continue;
107
+ }
108
+ $is_selected = ($default_source_language_id == $language_id);
109
+ $html .= '<option value="' . $store_id . '"' . ($is_selected ? ' selected="SELECTED"' : '') . '>' . $store->getName() . ' (' . $this->getLanguageNameByCode($language_code, true) . ')</option>';
110
+ }
111
+ $html .= '</select>';
112
+ return $html;
113
+ }
114
+
115
+ /**
116
+ * @param array $stores
117
+ * @param null $selectTagId
118
+ *
119
+ * @return string
120
+ */
121
+ public function getSourceLanguageSelectForOrderHtml(array $stores, $selectTagId = null) {
122
+
123
+ if (null == $selectTagId) {
124
+ $selectTagId = "store_language";
125
+ }
126
+ $default_source_language_id = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language');
127
+ $html = "<select id=\"$selectTagId\" class='translateto_select'>";
128
+ $html .= "<option class='disabled_item' disabled>";
129
+ foreach ($stores AS $store_id) {
130
+ $store = Mage::app()->getStore($store_id);
131
+ $language_code = $this->GetStoreLocale($store_id);
132
+ $language_id = $this->getLangByCode($language_code, true);
133
+ if (is_null($language_id)) {
134
+ // Language is unsupported
135
+ continue;
136
+ }
137
+ $is_selected = ($default_source_language_id == $language_id);
138
+ $html .= '<option value="' . $store_id . '"' . ($is_selected ? ' selected="SELECTED"' : '') . '>' . $store->getName() . ' (' . $this->getLanguageNameByCode($language_code, true) . ')</option>';
139
+ }
140
+ $html .= '</select>';
141
+ return $html;
142
+ }
143
+
144
+ public function getSourceLanguageArrayForStores($stores) {
145
+ $stores_array = array();
146
+ foreach ($stores AS $store) {
147
+ /** @var Mage_Core_Model_Store $store */
148
+ $store_language = $this->GetStoreLocale($store->getCode());
149
+ $language_id = $this->getLangByCode($store_language, true);
150
+ if (is_null($language_id)) {
151
+ // Language is unsupported
152
+ continue;
153
+ }
154
+ $stores_array[$store->getId()] = $this->getLanguageNameByCode($store_language, true) . ' (' . $store->getName() . ')';
155
+ }
156
+ return $stores_array;
157
+ }
158
+
159
+ public function DefaultProductFieldsToTranslate() {
160
+ return array(
161
+ 'name', 'short_description', 'description'
162
+ );
163
+ }
164
+
165
+ public function getSourceLanguageArray($store_ids, $default_source_language_id = null) {
166
+ $languages = array();
167
+ $selected_language = null;
168
+ $selected_language_store_id = null;
169
+ foreach ($store_ids as $store_id) {
170
+ $store = Mage::app()->getStore($store_id);
171
+ $language_code = $this->GetStoreLocale($store_id);
172
+ $language_id = $this->getLangByCode($language_code, true);
173
+ if (is_null($language_id)) {
174
+ // Language is unsupported
175
+ continue;
176
+ }
177
+ if (!$selected_language && $language_id == $default_source_language_id) {
178
+ $selected_language = $store->getName() . ' (' . $this->getLanguageNameByCode($language_code, true) . ')';
179
+ $selected_language_store_id = $store->getId();
180
+ continue;
181
+ }
182
+ $languages[(string)$store->getId()] = $store->getName() . ' (' . $this->getLanguageNameByCode($language_code, true) . ')';
183
+ }
184
+ if ($selected_language) {
185
+ $languages = array_reverse($languages, true);
186
+ $languages[(string)$selected_language_store_id] = $selected_language;
187
+ $languages = array_reverse($languages, true);
188
+ }
189
+ return $languages;
190
+ }
191
+
192
+ public function getLanguagesHtml($storeId = 0) {
193
+ $languages = $this->getLanguages();
194
+ $helper = Mage::helper('transfluenttranslate');
195
+
196
+ if (is_int($storeId)) {
197
+ $def = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language', $storeId);
198
+ } else {
199
+ $def = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_language', $helper->getStoreByCode($storeId));
200
+ }
201
+
202
+ $html = '<select id="translateto" class="translateto_select">';
203
+
204
+ foreach ($languages as $language) {
205
+ $selected = ($language['id'] == $def) ? ' selected="selected"' : '';
206
+ $html .= '<option value="' . $language['id'] . '"' . $selected . '>' . $language['name'] . '</option>';
207
+ }
208
+
209
+ $html .= '</select>';
210
+
211
+ return $html;
212
+ }
213
+
214
+ public function getLangById($id) {
215
+ $languages = $this->getLanguages();
216
+ $lang_code = '';
217
+
218
+ foreach ($languages as $lang) {
219
+ if ($lang['id'] == $id) {
220
+ $lang_code = $lang['code'];
221
+ }
222
+ }
223
+
224
+ return $lang_code;
225
+ }
226
+
227
+ public function GetStoreLocale($store_code) {
228
+ return Mage::getStoreConfig('general/locale/code', $store_code);
229
+ }
230
+
231
+ private function ConvertAlternativeCode($code) {
232
+ return str_replace('_', '-', strtolower($code));
233
+ }
234
+
235
+ public function getLanguageNameByCode($code, $alternative_formatting = false) {
236
+ if ($alternative_formatting) {
237
+ $code = $this->ConvertAlternativeCode($code);
238
+ }
239
+ $languages = $this->getLanguages();
240
+ foreach ($languages AS $language) {
241
+ if ($language['code'] == $code) {
242
+ return $language['name'];
243
+ }
244
+ }
245
+ return $code;
246
+ }
247
+
248
+ public function getLangByCode($code, $alternative_formatting = false) {
249
+ if ($alternative_formatting) {
250
+ $code = $this->ConvertAlternativeCode($code);
251
+ }
252
+ $languages = $this->getLanguages();
253
+ $lang_id = null;
254
+
255
+ foreach ($languages as $lang) {
256
+ if ($lang['code'] == $code) {
257
+ $lang_id = $lang['id'];
258
+ }
259
+ }
260
+
261
+ return $lang_id;
262
+ }
263
+
264
+ public function getQualityArray($default_level = null) {
265
+ $levels = array(
266
+ '1' => 'Native speaker (powered by Gengo)',
267
+ '2' => 'Professional translator',
268
+ //'3' => 'Pair of prof. translators'
269
+ );
270
+ $levels_out = array();
271
+ if ($default_level) {
272
+ $levels_out[$default_level] = $levels[$default_level];
273
+ }
274
+ foreach ($levels AS $level_id => $level_desc) {
275
+ if ($level_id == $default_level) {
276
+ continue;
277
+ }
278
+ $levels_out[$level_id] = $level_desc;
279
+ }
280
+ return $levels_out;
281
+ }
282
+
283
+ public function getQualityValue($id) {
284
+ $arr = $this->getQualityArray();
285
+
286
+ return $arr[$id];
287
+ }
288
+
289
+ public function getQualityCode($val) {
290
+ $arr = $this->getQualityArray();
291
+ $id = '';
292
+
293
+ foreach ($arr as $key => $_a) {
294
+ if ($_a == $val) {
295
+ $id = $key;
296
+ }
297
+ }
298
+
299
+ return $id;
300
+ }
301
+
302
+ public function getQualityHtml($storeId = 0) {
303
+ $qualities = $this->getQualityArray();
304
+ $helper = Mage::helper('transfluenttranslate');
305
+
306
+ if (is_int($storeId)) {
307
+ $def = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_quality', $storeId);
308
+ } else {
309
+ $def = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_default_quality', $helper->getStoreByCode($storeId));
310
+ }
311
+
312
+ $html = '<select id="tf_translate_level" class="translate_quality">';
313
+ foreach ($qualities as $quality => $value) {
314
+ $selected = ($quality == $def) ? ' selected="selected"' : '';
315
+ $html .= '<option value="' . $quality . '"' . $selected . '>' . $value . '</option>';
316
+ }
317
+ $html .= '</select>';
318
+
319
+ return $html;
320
+ }
321
+
322
+ /**
323
+ * get translate fields
324
+ *
325
+ * @param Mage_Core_Model_Abstract $product
326
+ * @param $force_translate
327
+ * @param $store_to_id
328
+ * @param $fields_to_translate_in
329
+ *
330
+ * @return mixed
331
+ */
332
+ public function getTranslateFields(Mage_Core_Model_Abstract $product, $force_translate, $store_to_id, $fields_to_translate_in) {
333
+
334
+ $fieldData = $this->GetTranslationFieldData($product, $force_translate, $store_to_id, $fields_to_translate_in);
335
+ return $fieldData['translateFields'];
336
+ }
337
+
338
+ /**
339
+ * @param Mage_Core_Model_Abstract $product
340
+ * @param $force_translate
341
+ * @param $store_to_id
342
+ * @param $fields_to_translate_in
343
+ *
344
+ * @return mixed
345
+ */
346
+ public function getAlreadyTranslatedFields(Mage_Core_Model_Abstract $product, $force_translate, $store_to_id, $fields_to_translate_in) {
347
+ $fieldData = $this->GetTranslationFieldData($product, $force_translate, $store_to_id, $fields_to_translate_in);
348
+ return $fieldData['alreadyTranslatedFields'];
349
+ }
350
+
351
+ /**
352
+ * @param Mage_Core_Model_Abstract $product
353
+ * @param $force_translate
354
+ * @param $store_to_id
355
+ * @param $fields_to_translate_in
356
+ *
357
+ * @return array
358
+ */
359
+ private function GetTranslationFieldData(Mage_Core_Model_Abstract $product, $force_translate, $store_to_id, $fields_to_translate_in) {
360
+ $model = Mage::getModel('catalog/product');
361
+ /** @var Mage_Catalog_Model_Product $model */
362
+
363
+ $translated_product = $model->setStoreId($store_to_id)->load($product->getId());
364
+ /** @var Mage_Catalog_Model_Product $translated_product */
365
+
366
+ $language_helper = Mage::helper('transfluenttranslate/languages');
367
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
368
+
369
+ $fields_already_translated = array();
370
+ $translate_fields = array();
371
+ if (empty($fields_to_translate_in)) {
372
+ foreach ($language_helper->DefaultProductFieldsToTranslate() AS $default_field_to_translate) {
373
+ if ($force_translate || !$translated_product->getExistsStoreValueFlag($default_field_to_translate)) {
374
+ $translate_fields[] = $default_field_to_translate;
375
+ } else {
376
+ $fields_already_translated[] = $default_field_to_translate;
377
+ }
378
+ }
379
+ } else {
380
+ foreach ($fields_to_translate_in AS $field_to_translate) {
381
+ if ($force_translate || !$translated_product->getExistsStoreValueFlag($field_to_translate)) {
382
+ $translate_fields[] = $field_to_translate;
383
+ } else {
384
+ $fields_already_translated[] = $field_to_translate;
385
+ }
386
+ }
387
+ }
388
+
389
+ return array(
390
+ 'translateFields' => $translate_fields,
391
+ 'alreadyTranslatedFields' => $fields_already_translated
392
+ );
393
+ }
394
+ }
app/code/community/Transfluent/Translate/Helper/Product.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Helper_Product extends Mage_Core_Helper_Abstract
8
+ {
9
+ /**
10
+ * @param $store_id
11
+ * @param $text_id
12
+ * @param $level
13
+ *
14
+ * @return Mage_Catalog_Model_Resource_Product_Collection
15
+ */
16
+ public function GetOrder($store_id, $text_id, $level)
17
+ {
18
+ $order_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
19
+ return $order_model->getCollection()
20
+ ->addFieldToFilter('text_id', $text_id)
21
+ //->addFieldToFilter('source_store', $source_store)
22
+ ->addFieldToFilter('target_store', $store_id)
23
+ ->addFieldToFilter('level', $level);
24
+ }
25
+
26
+ /**
27
+ * get product attributes
28
+ *
29
+ * @param Mage_Catalog_Model_Product $product
30
+ * @param array $translate_fields
31
+ *
32
+ * @return array
33
+ */
34
+ public function GetProductAttribute(Mage_Catalog_Model_Product $product, array $translate_fields)
35
+ {
36
+
37
+ if (empty($product)) {
38
+ return array();
39
+ }
40
+
41
+ /** @var Transfluent_Translate_Helper_Constant $constant_helper */
42
+ $constant_helper = Mage::helper('transfluenttranslate/constant');
43
+ $non_translatable_attributes = $constant_helper->getNonTranslatableAttributes();
44
+
45
+ $productAttributes = array();
46
+ foreach ($product->getAttributes() AS $attribute) {
47
+ /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
48
+ if (!$attribute->getIsVisible() || $attribute->isStatic() || $attribute->isDeleted() || $attribute->getIsGlobal()) {
49
+ continue;
50
+ }
51
+ if (in_array($attribute->getName(), $non_translatable_attributes)) {
52
+ continue;
53
+ }
54
+ if ($attribute->usesSource()) {
55
+ continue;
56
+ }
57
+
58
+ $productAttributes[] = array(
59
+ 'name' => Mage::helper('core')->quoteEscape($attribute->getName()),
60
+ 'selected' => (in_array($attribute->getName(), $translate_fields) ? true : false),
61
+ 'label' => Mage::helper('core')->quoteEscape($attribute->getFrontend()->getLabel())
62
+ );
63
+ }
64
+
65
+ return $productAttributes;
66
+ }
67
+ }
app/code/community/Transfluent/Translate/Helper/Tag.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Helper_Tag
5
+ */
6
+ class Transfluent_Translate_Helper_Tag extends Mage_Core_Helper_Abstract
7
+ {
8
+ /**
9
+ * @param array $tags
10
+ * @param $store_from_id
11
+ *
12
+ * @return array
13
+ */
14
+ public function getTags(array $tags, $store_from_id)
15
+ {
16
+ $model = Mage::getModel('tag/tag');
17
+ /** @var Mage_Tag_Model_Tag $model */
18
+ $tag_models = array();
19
+ foreach ($tags AS $tag_id) {
20
+ $tag = $model->setStoreId($store_from_id)->load($tag_id);
21
+ /** @var Mage_Tag_Model_Tag $tag */
22
+ if (!$tag || !$tag->getId()) {
23
+ continue;
24
+ }
25
+ if (!$tag->isAvailableInStore($store_from_id)) {
26
+ continue;
27
+ }
28
+ /** @var Mage_Tag_Model_Tag $tag */
29
+ $tag_models[] = $tag;
30
+ }
31
+
32
+ return $tag_models;
33
+ }
34
+
35
+ }
app/code/community/Transfluent/Translate/Helper/Text.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Helper_Text extends Mage_Core_Helper_Abstract {
8
+ private $_handlers = array(
9
+ "/store\-([0-9]{1,})\-tag\-([0-9]{1,})/" => 'Transfluent_Translate_Model_TagName',
10
+ "/store\-([0-9]{1,})\-product\-([0-9]{1,})\-(.*)/" => 'Transfluent_Translate_Model_ProductDetail',
11
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-([a-z\-]{1,})/" => 'Transfluent_Translate_Model_CategoryDetail',
12
+ "/store\-([0-9]{1,})\-attribute\-([0-9]{1,})\-option\-([0-9]{1,})/" => 'Transfluent_Translate_Model_AttributeOption',
13
+ "/store\-([0-9]{1,})\-attribute\-([0-9]{1,})/" => 'Transfluent_Translate_Model_AttributeName',
14
+ );
15
+
16
+ public function ModelByTextId($text_id) {
17
+ $status = null;
18
+ foreach ($this->_handlers AS $pattern => $class_name) {
19
+ if (preg_match($pattern, $text_id, $matches)) {
20
+ $object = new $class_name();
21
+ $object->SetTextId($text_id);
22
+ return $object;
23
+ }
24
+ }
25
+ return null;
26
+ }
27
+ }
app/code/community/Transfluent/Translate/Helper/Util.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Helper_Util
5
+ */
6
+ class Transfluent_Translate_Helper_Util extends Mage_Core_Helper_Abstract
7
+ {
8
+ /**
9
+ * get success json message
10
+ *
11
+ * @param $string
12
+ * @return string
13
+ */
14
+ public function getSuccessJson($string)
15
+ {
16
+ return json_encode(array('status' => 'success', 'message' => htmlspecialchars($string)));
17
+ }
18
+
19
+ /**
20
+ * get error json message
21
+ *
22
+ * @param $string
23
+ * @return string
24
+ */
25
+ public function getErrorJson($string)
26
+ {
27
+ return json_encode(array('status' => 'error', 'message' => htmlspecialchars($string)));
28
+ }
29
+ }
app/code/community/Transfluent/Translate/Model/AttributeName.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_AttributeName extends Mage_Core_Model_Abstract {
8
+ protected $_text_id;
9
+ protected $_store;
10
+ protected $_attribute_id;
11
+
12
+ public function _construct() {
13
+ parent::_construct();
14
+ }
15
+
16
+ public function SetTextId($text_id) {
17
+ if (!preg_match("/store\-([0-9]{1,})\-attribute\-([0-9]{1,})/", $text_id, $matches)) {
18
+ throw new Exception('Invalid text id');
19
+ }
20
+ $this->_text_id = $text_id;
21
+ $this->_store = $matches[1];
22
+ $this->_attribute_id = $matches[2];
23
+ }
24
+
25
+ public function Attribute() {
26
+ try {
27
+ $model = Mage::getModel('eav/entity_attribute')->load($this->_attribute_id);
28
+ } catch (Exception $e) {
29
+ return null;
30
+ }
31
+ /** @var Mage_Eav_Model_Entity_Attribute $model */
32
+ if ($model && $model->getId()) {
33
+ return $model;
34
+ }
35
+ return null;
36
+ }
37
+
38
+ public function OrderTitle() {
39
+ $attribute = $this->Attribute();
40
+ $title = Mage::helper('transfluenttranslate/text')->__('Attribute');
41
+ if ($attribute) {
42
+ $title .= ': ' . $attribute->getStoreLabel($this->_store);
43
+ }
44
+ return $title;
45
+ }
46
+ }
app/code/community/Transfluent/Translate/Model/AttributeOption.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_AttributeOption extends Transfluent_Translate_Model_AttributeName {
8
+ private $_option_id;
9
+
10
+ public function SetTextId($text_id) {
11
+ if (!preg_match("/store\-([0-9]{1,})\-attribute\-([0-9]{1,})\-option\-([0-9]{1,})/", $text_id, $matches)) {
12
+ throw new Exception('Invalid text id');
13
+ }
14
+ $this->_text_id = $text_id;
15
+ $this->_store = $matches[1];
16
+ $this->_attribute_id = $matches[2];
17
+ $this->_option_id = $matches[3];
18
+ }
19
+
20
+ public function OrderTitle() {
21
+ $attribute = $this->Attribute();
22
+ $title = Mage::helper('transfluenttranslate/text')->__('Attribute option');
23
+ if ($attribute) {
24
+ $title .= ': ' . $attribute->getStoreLabel($this->_store);
25
+ }
26
+ if ($attribute && $attribute->usesSource()) {
27
+ try {
28
+ $title .= ' - ' . $attribute->getSource()->getOptionText($this->_option_id);
29
+ } catch (Exception $e) {
30
+ }
31
+ }
32
+ return $title;
33
+ }
34
+ }
app/code/community/Transfluent/Translate/Model/Base/Backendclient.php ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Base_Backendclient extends Mage_Adminhtml_Controller_Action {
8
+ const HTTP_GET = 'GET';
9
+ const HTTP_POST = 'POST';
10
+ const PRODUCTION_HOST = 'https://transfluent.com/v2/';
11
+ const DEV_HOST_CONFIG_FILE = 'dev_host.config';
12
+
13
+ static $API_URL;
14
+ static $DEV_MODE = false;
15
+ private $email;
16
+ private $token = null;
17
+
18
+ public function __construct() {
19
+ $email = Mage::getStoreConfig('transfluenttranslate/account/email');
20
+ $token = Mage::getStoreConfig('transfluenttranslate/account/token');
21
+
22
+ $this->SystemCheck();
23
+ $this->email = $email;
24
+ $this->token = $token;
25
+
26
+ $this->setApiUrl($this->getBackendHost());
27
+ }
28
+
29
+ /**
30
+ * setter for API_URL
31
+ *
32
+ * @param $url
33
+ */
34
+ private function setApiUrl($url) {
35
+ if (filter_var($url, FILTER_VALIDATE_URL)) {
36
+ self::$API_URL = $url;
37
+ }
38
+
39
+ if (self::PRODUCTION_HOST != $url) {
40
+ $this->setDevMode(true);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * getter for API_URL
46
+ *
47
+ * @return string
48
+ */
49
+ public function getApiUrl() {
50
+ return self::$API_URL;
51
+ }
52
+
53
+ /**
54
+ * getter for DEV_MODE
55
+ *
56
+ * @return bool
57
+ */
58
+ public function getDevMode() {
59
+ return self::$DEV_MODE;
60
+ }
61
+
62
+ /**
63
+ * setter for DEV_MODE
64
+ *
65
+ * @param $mode
66
+ */
67
+ private function setDevMode($mode) {
68
+
69
+ if (true === $mode || false === $mode) {
70
+ self::$DEV_MODE = $mode;
71
+ }
72
+ }
73
+
74
+ private function UriFromMethod($method_name) {
75
+ return strtolower(preg_replace("/(?!^)([A-Z]{1}[a-z0-9]{1,})/", '/$1', $method_name)) . '/';
76
+ }
77
+
78
+ private function SystemCheck() {
79
+ if (function_exists('curl_init')) {
80
+ return;
81
+ }
82
+ Mage::getSingleton('core/session')->addError('Transfluent\'s extension is missing cURL for PHP. Please install it now!');
83
+ error_log('Transfluent\'s ' . __CLASS__ . ' is missing cURL extension for PHP.');
84
+ }
85
+
86
+
87
+ public function SetToken($token) {
88
+ $this->token = $token;
89
+ }
90
+
91
+ public function getToken() {
92
+ return $this->token;
93
+ }
94
+
95
+ /**
96
+ * provides backend host name
97
+ *
98
+ * @return string
99
+ */
100
+ public function getBackendHost() {
101
+
102
+ $API_URL = self::PRODUCTION_HOST;
103
+ $dev_host_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . self::DEV_HOST_CONFIG_FILE;
104
+ if (is_file($dev_host_file)) {
105
+ $API_URL = trim(file_get_contents($dev_host_file));
106
+ }
107
+
108
+ return $API_URL;
109
+ }
110
+
111
+ private function SaveConfiguration($email, $token) {
112
+ try {
113
+ $coreConfig = Mage::getModel('core/config');
114
+ $coreConfig->saveConfig('transfluenttranslate/account/email', $email);
115
+ $coreConfig->saveConfig('transfluenttranslate/account/token', $token);
116
+ Mage::getConfig()->reinit();
117
+ Mage::app()->reinitStores();
118
+ } catch (Exception $e) {
119
+ return false;
120
+ }
121
+ return true;
122
+ }
123
+
124
+ public function Logout() {
125
+ // @todo: Notify API about logout
126
+ return $this->SaveConfiguration(null, null);
127
+ }
128
+
129
+ public function Authenticate($e, $p) {
130
+ $response = $this->Request(__FUNCTION__, 'POST', array('email' => $e, 'password' => $p));
131
+ $message = array();
132
+ if (!$response['response']['token']) {
133
+ throw new Exception('Could not authenticate with API!');
134
+ }
135
+ if ($response['status'] == 'ERROR') {
136
+ $message['status'] = 'error';
137
+ $message['message'] = $response['error']['message'] . ' ' . $response['response'];
138
+ } else {
139
+ $token = $response['response']['token'];
140
+ $this->token = $token;
141
+ $this->email = $e;
142
+ $this->SaveConfiguration($e, $token);
143
+ $message['status'] = 'ok';
144
+ $message['message'] = 'You have successfully connected to Transfluent.com';
145
+ $session = Mage::getSingleton('core/session');
146
+ /** @var Mage_Core_Model_Session $session */
147
+ $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.');
148
+ }
149
+ return $message;
150
+ }
151
+
152
+ /**
153
+ * /languages/ can be called without token&any authentication, we can call Request directly
154
+ *
155
+ * @throws \Exception
156
+ * @return mixed
157
+ */
158
+ public function Languages() {
159
+ return $this->Request(__FUNCTION__);
160
+ }
161
+
162
+ public function Hello() {
163
+ return $this->CallApi(__FUNCTION__, self::HTTP_GET, array('name' => 'tests'));
164
+ }
165
+
166
+ public function CreateAccount($email, $terms) {
167
+ $res = $this->CallApi(__FUNCTION__, self::HTTP_GET, array('email' => $email, 'terms' => $terms));
168
+ if ($res['status'] == "OK") {
169
+ $this->SaveConfiguration($email, $res['response']['token']);
170
+ $session = Mage::getSingleton('core/session');
171
+ /** @var Mage_Core_Model_Session $session */
172
+ $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.');
173
+ }
174
+ return $res;
175
+ }
176
+
177
+ public function SaveText($text_id, $language, $text) {
178
+ return $this->CallApi('text', self::HTTP_POST, array(
179
+ 'text_id' => $text_id,
180
+ 'group_id' => 'Magento',
181
+ 'language' => $language,
182
+ 'text' => $text,
183
+ 'token' => $this->token
184
+ ));
185
+ }
186
+
187
+ public function Text($text_id, $source_language, $text, $token, $method) {
188
+ return $this->CallApi(__FUNCTION__, $method, array(
189
+ 'text_id' => $text_id,
190
+ 'language' => $source_language,
191
+ 'text' => $text,
192
+ 'token' => $token
193
+ ));
194
+ }
195
+
196
+ public function Texts($group_id, $source_language, $texts, $it, $method, $token) {
197
+ return $this->CallApi(__FUNCTION__, $method, array(
198
+ 'group_id' => $group_id,
199
+ 'language' => $source_language,
200
+ 'texts' => $texts,
201
+ 'invalidate_translations' => $it,
202
+ 'token' => $token
203
+ ));
204
+ }
205
+
206
+ public function TextsTranslate($group_id = null, $source_language, $target_languages, $texts, $comment, $callback_url, $level) {
207
+ return $this->CallApi(__FUNCTION__, self::HTTP_POST, array(
208
+ 'group_id' => $group_id,
209
+ 'source_language' => $source_language,
210
+ 'target_languages' => $target_languages, //'[500]',
211
+ 'texts' => $texts,
212
+ 'comment' => $comment,
213
+ 'callback_url' => $callback_url,
214
+ 'level' => $level,
215
+ 'token' => $this->token
216
+ ));
217
+ }
218
+
219
+ public function TextStatus($text_id, $source_language, $token) {
220
+ return $this->CallApi(__FUNCTION__, self::HTTP_GET, array(
221
+ 'text_id' => $text_id,
222
+ 'language' => $source_language,
223
+ 'token' => $token
224
+ ));
225
+ }
226
+
227
+ public function FreeTextWordCount($level, $text, $source_language_id, $target_language_id) {
228
+ return $this->CallApi(__FUNCTION__, self::HTTP_POST, array(
229
+ 'free_text' => $text,
230
+ 'level' => $level,
231
+ 'source_language' => $source_language_id,
232
+ 'target_language' => $target_language_id,
233
+ 'token' => $this->token
234
+ ));
235
+ }
236
+
237
+ public function TextWordCount($level, $text_id, $group_id, $source_language, $text, $it = 0, $locale, $token) {
238
+ return $this->CallApi(__FUNCTION__, self::HTTP_GET, array(
239
+ 'level' => $level,
240
+ 'text_id' => $text_id,
241
+ 'group_id' => $group_id,
242
+ 'language' => $source_language,
243
+ 'text' => $text,
244
+ 'invalidate_translations' => $it,
245
+ 'locale' => $locale,
246
+ 'token' => $token
247
+ ));
248
+ }
249
+
250
+ private function CallApi($method_name, $method = self::HTTP_GET, $payload = array()) {
251
+ return $this->Request($method_name, $method, $payload);
252
+ }
253
+
254
+ private function Request($method_name, $method = self::HTTP_GET, $payload = array()) {
255
+ $uri = $this->UriFromMethod($method_name);
256
+
257
+ $curl_handle = curl_init(self::$API_URL . $uri);
258
+ if (!$curl_handle) {
259
+ throw new \Exception('Could not initialize cURL!');
260
+ }
261
+ switch (strtoupper($method)) {
262
+ case self::HTTP_GET:
263
+ $url = self::$API_URL . $uri . '?';
264
+ $url_parameters = array();
265
+ foreach ($payload AS $key => $value) {
266
+ $url_parameters[] = $key . '=' . urlencode($value);
267
+ }
268
+ $url .= implode("&", $url_parameters);
269
+ curl_setopt($curl_handle, CURLOPT_URL, $url);
270
+ break;
271
+ case self::HTTP_POST:
272
+ curl_setopt($curl_handle, CURLOPT_POST, TRUE);
273
+ if (!empty($payload)) {
274
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $payload);
275
+ }
276
+ break;
277
+ default:
278
+ throw new \Exception('Unsupported request method.');
279
+ }
280
+ curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1);
281
+ curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
282
+ if (self::$DEV_MODE) {
283
+ curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
284
+ }
285
+ $response = curl_exec($curl_handle);
286
+ $info = curl_getinfo($curl_handle);
287
+ curl_close($curl_handle);
288
+
289
+
290
+ if (!$response) {
291
+ throw new \Exception('Failed to connect with Transfluent\'s API. cURL error: ' . curl_error($curl_handle));
292
+ }
293
+ // !isset($info['http_code']) || $info['http_code'] != 200
294
+ try {
295
+ $response_obj = Mage::helper('core')->jsonDecode($response, true);
296
+ } catch (Exception $e) {
297
+ if ($info['http_code'] == 500) {
298
+ throw new Exception('The order could not be processed. Please try again!');
299
+ }
300
+ if (self::$DEV_MODE) {
301
+ error_log('API sent invalid JSON response: ' . $response . ', info: ' . print_r($info, true));
302
+ }
303
+ throw $e;
304
+ }
305
+
306
+ return $response_obj;
307
+ }
308
+ }
app/code/community/Transfluent/Translate/Model/CategoryDetail.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_CategoryDetail extends Mage_Core_Model_Abstract {
8
+ private $_text_id;
9
+ private $_store;
10
+ private $_category_id;
11
+ private $_detail_name;
12
+
13
+ public function _construct() {
14
+ parent::_construct();
15
+ }
16
+
17
+ public function SetTextId($text_id) {
18
+ if (!preg_match("/store\-([0-9]{1,})\-category\-([0-9]{1,})\-([a-z\-]{1,})/", $text_id, $matches)) {
19
+ throw new Exception('Invalid text id');
20
+ }
21
+ $this->_text_id = $text_id;
22
+ $this->_store = $matches[1];
23
+ $this->_category_id = $matches[2];
24
+ $this->_detail_name = $matches[3];
25
+ }
26
+
27
+ public function Category() {
28
+ $model = Mage::getModel('catalog/category')->setStoreId($this->_store)->load($this->_category_id);
29
+ /** @var Mage_Catalog_Model_Category $model */
30
+ if ($model && $model->getId()) {
31
+ return $model;
32
+ }
33
+ return null;
34
+ }
35
+
36
+ public function OrderTitle() {
37
+ $category = $this->Category();
38
+ $title = '';
39
+ switch ($this->_detail_name) {
40
+ case 'name':
41
+ $title .= Mage::helper('transfluenttranslate/text')->__('Category');
42
+ break;
43
+ case 'description':
44
+ $title .= Mage::helper('transfluenttranslate/text')->__('Category description');
45
+ break;
46
+ case 'meta-description':
47
+ $title .= Mage::helper('transfluenttranslate/text')->__('Category meta description');
48
+ break;
49
+ case 'meta-title':
50
+ $title .= Mage::helper('transfluenttranslate/text')->__('Category meta title');
51
+ break;
52
+ case 'meta-keywords':
53
+ $title .= Mage::helper('transfluenttranslate/text')->__('Category meta keywords');
54
+ break;
55
+ }
56
+ if ($category) {
57
+ $title .= ': ' . '<a href="' . $category->getUrl() . '">' . $category->getName() . '</a>';
58
+ }
59
+ return $title;
60
+ }
61
+ }
app/code/community/Transfluent/Translate/Model/Config/Source/Fromlang.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Config_Source_Fromlang extends Varien_Data_Collection {
8
+ public function toOptionArray() {
9
+ $options = array();
10
+ $languages = Mage::helper('transfluenttranslate/languages')->getLanguages();
11
+ foreach ($languages as $language) {
12
+ $options[] = array(
13
+ 'label' => $language['name'],
14
+ 'value' => $language['id']
15
+ );
16
+ }
17
+ return ($options);
18
+ }
19
+ }
app/code/community/Transfluent/Translate/Model/Config/Source/Language.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Config_Source_Language extends Varien_Data_Collection {
8
+ public function toOptionArray() {
9
+ $options = array();
10
+ $languages = Mage::helper('transfluenttranslate/languages')->getLanguages();
11
+
12
+ $options[] = array('value' => '0', 'label' => '(Please choose one language)');
13
+ foreach ($languages as $language) {
14
+ $options[] = array(
15
+ 'value' => $language['id'],
16
+ 'label' => $language['name']
17
+ );
18
+ }
19
+ return ($options);
20
+ }
21
+ }
app/code/community/Transfluent/Translate/Model/Config/Source/Quality.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Config_Source_Quality extends Varien_Data_Collection {
8
+ public function toOptionArray() {
9
+ $options = array();
10
+ $levels = Mage::helper('transfluenttranslate/languages')->getQualityArray();
11
+ $options[] = array('value' => '0', 'label' => '');
12
+
13
+ foreach ($levels AS $key => $level) {
14
+ $options[] = array(
15
+ 'value' => $key,
16
+ 'label' => $level
17
+ );
18
+ }
19
+ return ($options);
20
+ }
21
+ }
app/code/community/Transfluent/Translate/Model/Debugutil.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Model_Debugutil
5
+ */
6
+ class Transfluent_Translate_Model_Debugutil extends Mage_Core_Model_Abstract {
7
+
8
+ /** @var string tempFile */
9
+ public $tempFile = '/tmp/magento_transfluent.log';
10
+
11
+ /**
12
+ *
13
+ */
14
+ public function __construct() {
15
+ }
16
+
17
+ /**
18
+ * @param $stacktrace
19
+ *
20
+ * @return string
21
+ */
22
+ public function callStack($stacktrace) {
23
+ $result = str_repeat("=", 10) . " " . date(now()) . " " . str_repeat("=", 10) . "\n";
24
+ $i = 1;
25
+ foreach ($stacktrace as $node) {
26
+ $result .= "$i. " . basename($node['file']) . ":" . $node['function'] . "(" . $node['line'] . ")\n";
27
+ $i++;
28
+ }
29
+
30
+ return $result;
31
+ }
32
+
33
+ /**
34
+ * writes stacktrace to temp file
35
+ *
36
+ * @param null $stackTrace
37
+ * @param null $fileName
38
+ */
39
+ public function callStackToTemp($stackTrace = null, $fileName = null) {
40
+ if (null == $stackTrace) {
41
+ $stackTrace = debug_backtrace();
42
+ }
43
+
44
+ if (null != $fileName) {
45
+ $this->tempFile = $fileName;
46
+ }
47
+
48
+ file_put_contents($this->tempFile, PHP_EOL . self::callStack($stackTrace) . PHP_EOL, FILE_APPEND | LOCK_EX);
49
+ }
50
+
51
+ /**
52
+ * pushes a string to temp file
53
+ *
54
+ * @param null $value
55
+ * @param null $fileName
56
+ */
57
+ public function valueToTemp($value = null, $fileName = null) {
58
+ if (null != $fileName) {
59
+ $this->tempFile = $fileName;
60
+ }
61
+
62
+ if (is_array($value) || is_object($value)) {
63
+ $value = var_export($value, true);
64
+ }
65
+
66
+ file_put_contents($this->tempFile, PHP_EOL . $value . PHP_EOL, FILE_APPEND | LOCK_EX);
67
+ }
68
+ }
app/code/community/Transfluent/Translate/Model/Mysql4/Transfluenttranslate.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Mysql4_Transfluenttranslate extends Mage_Core_Model_Mysql4_Abstract {
8
+ public function _construct() {
9
+ $this->_init('transfluenttranslate/transfluenttranslate', 'id');
10
+ }
11
+ }
app/code/community/Transfluent/Translate/Model/Mysql4/Transfluenttranslate/Collection.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Mysql4_Transfluenttranslate_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
8
+ public function _construct() {
9
+ $this->_init('transfluenttranslate/transfluenttranslate');
10
+ }
11
+ }
app/code/community/Transfluent/Translate/Model/Observer.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Observer extends Mage_Core_Model_Abstract {
8
+ /**
9
+ * @version 1.1.1
10
+ * @param Varien_Event_Observer $observer
11
+ * @return Mage_Core_Block_Template
12
+ */
13
+ private function _createTranslateFormBlock(Varien_Event_Observer $observer) {
14
+ $block = new Mage_Core_Block_Template();
15
+ $block->setTemplate('transfluent/product/edit.phtml');
16
+ $block->setIsAnonymous(true);
17
+ return $block;
18
+ }
19
+
20
+ /**
21
+ * @version 1.1.1
22
+ * @param Varien_Event_Observer $observer
23
+ * @return Mage_Core_Block_Template
24
+ */
25
+ private function _createGetQuoteFormBlock(Varien_Event_Observer $observer) {
26
+ $block = new Mage_Core_Block_Template();
27
+ $block->setTemplate('transfluent/product/index.phtml');
28
+ $block->setIsAnonymous(true);
29
+ return $block;
30
+ }
31
+
32
+ /**
33
+ * @version 1.1.1
34
+ * @param Varien_Event_Observer $observer
35
+ * @return Mage_Core_Block_Template
36
+ */
37
+ private function _createTranslateAttributesFormBlock(Varien_Event_Observer $observer) {
38
+ $block = new Mage_Core_Block_Template();
39
+ $block->setTemplate('transfluent/product/attributes/edit.phtml');
40
+ $block->setIsAnonymous(true);
41
+ return $block;
42
+ }
43
+
44
+ /**
45
+ * @version 1.1.1
46
+ * @param Varien_Event_Observer $observer
47
+ * @return Mage_Core_Block_Template
48
+ */
49
+ private function _createTranslateCategoriesFormBlock(Varien_Event_Observer $observer) {
50
+ $block = new Mage_Core_Block_Template();
51
+ $block->setTemplate('transfluent/product/category/edit.phtml');
52
+ $block->setIsAnonymous(true);
53
+ return $block;
54
+ }
55
+
56
+ /**
57
+ * @version 1.1.1
58
+ * @param Varien_Event_Observer $observer
59
+ * @return Mage_Core_Block_Template
60
+ */
61
+ private function _createTranslateTagsFormBlock(Varien_Event_Observer $observer) {
62
+ $block = new Mage_Core_Block_Template();
63
+ $block->setTemplate('transfluent/tag/tag/index.phtml');
64
+ $block->setIsAnonymous(true);
65
+ return $block;
66
+ }
67
+
68
+ /**
69
+ * @version 1.1.1
70
+ * @param Varien_Event_Observer $observer
71
+ */
72
+ public function hookDispatchAdminhtmlBlockHtmlBefore(Varien_Event_Observer $observer) {
73
+ if (!Mage::getStoreConfig('transfluenttranslate/account/token')) {
74
+ return;
75
+ }
76
+ $action = Mage::app()->getRequest()->getRequestedActionName();
77
+ switch (Mage::app()->getRequest()->getControllerName()) {
78
+ case 'catalog_product':
79
+ switch ($action) {
80
+ case 'index':
81
+ $this->AddGetQuoteBlockToProductIndexPage($observer);
82
+ break;
83
+ case 'edit':
84
+ $this->AddTranslateBlockToProductEditPage($observer);
85
+ break;
86
+ }
87
+ return;
88
+ case 'catalog_category':
89
+ if ($action != 'edit') return;
90
+ $this->AddTranslateBlockToCategoryEditPage($observer);
91
+ break;
92
+ case 'catalog_product_attribute':
93
+ if ($action != 'edit') return;
94
+ $this->AddTranslateBlockToProductAttributesEditPage($observer);
95
+ break;
96
+ case 'tag':
97
+ if ($action != 'index') return;
98
+ $this->AddTranslateBlockToTagIndexPage($observer);
99
+ break;
100
+ default:
101
+ return;
102
+ }
103
+ }
104
+
105
+ private function AddTranslateBlockToTagIndexPage(Varien_Event_Observer $observer) {
106
+ $block = $observer->getEvent()->getBlock();
107
+ /** @var Mage_Core_Block_Abstract $block */
108
+ if ($block->getNameInLayout() == 'root') {
109
+ $extendBlock = $this->_createTranslateTagsFormBlock($observer);
110
+ if ($extendBlock) {
111
+ $block->getChild('content')->insert($extendBlock, '', false, 'TF_Translate_form');
112
+ }
113
+ }
114
+ }
115
+
116
+ private function AddTranslateBlockToProductAttributesEditPage(Varien_Event_Observer $observer) {
117
+ $block = $observer->getEvent()->getBlock();
118
+ /** @var Mage_Core_Block_Abstract $block */
119
+ if ($block->getNameInLayout() == 'root') {
120
+ $extendBlock = $this->_createTranslateAttributesFormBlock($observer);
121
+ if ($extendBlock) {
122
+ $block->getChild('content')->insert($extendBlock, '', false, 'TF_Translate_form');
123
+ }
124
+ }
125
+ }
126
+
127
+ private function IsAjax() {
128
+ return Mage::app()->getRequest()->isXmlHttpRequest() || Mage::app()->getRequest()->getParam('isAjax');
129
+ }
130
+
131
+ private function AddTranslateBlockToCategoryEditPage(Varien_Event_Observer $observer) {
132
+ if ($this->IsAjax()) {
133
+ return;
134
+ }
135
+ $block = $observer->getEvent()->getBlock();
136
+ /** @var Mage_Core_Block_Abstract $block */
137
+ if ($block->getNameInLayout() == 'root') {
138
+ $extendBlock = $this->_createTranslateCategoriesFormBlock($observer);
139
+ if ($extendBlock) {
140
+ $block->getChild('content')->insert($extendBlock, '', false, 'TF_Translate_form');
141
+ }
142
+ }
143
+ }
144
+
145
+ private function AddTranslateBlockToProductEditPage(Varien_Event_Observer $observer) {
146
+ $block = $observer->getEvent()->getBlock();
147
+ /** @var Mage_Core_Block_Abstract $block */
148
+ if ($block->getNameInLayout() == 'root') {
149
+ $extendBlock = $this->_createTranslateFormBlock($observer);
150
+ if ($extendBlock) {
151
+ $block->getChild('content')->insert($extendBlock, '', false, 'TF_Translate_form');
152
+ }
153
+ }
154
+ }
155
+
156
+ private function AddGetQuoteBlockToProductIndexPage(Varien_Event_Observer $observer) {
157
+ $block = $observer->getEvent()->getBlock();
158
+ /** @var Mage_Core_Block_Abstract $block */
159
+ if ($block->getNameInLayout() == 'root') {
160
+ $extendBlock = $this->_createGetQuoteFormBlock($observer);
161
+ if ($extendBlock) {
162
+ $block->getChild('content')->insert($extendBlock, '', false, 'TF_Translate_form');
163
+ }
164
+ }
165
+ }
166
+
167
+ public function hookDispatchSaveProduct(Varien_Event_Observer $observer) {
168
+ // @todo: Save changes to source language?
169
+ /*
170
+ $product = $observer->getEvent()->getProduct();
171
+ $storeId = $product->getStoreId();
172
+ $sku = $product->getSku();
173
+ $tran_mod = Mage::getModel('transfluenttranslate/transfluenttranslate');
174
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
175
+ $lang_helper = Mage::helper('transfluenttranslate/languages');
176
+
177
+ $pendings = $tran_mod
178
+ ->getCollection()
179
+ ->addFieldToFilter('transfluenttranslate_store', $storeId)
180
+ ->addFieldToFilter('transfluenttranslate_product', $sku)
181
+ ->addFieldToFilter('transfluenttranslate_status', 'Pending')
182
+ ->addFieldToFilter('transfluenttranslate_groupid', 0)
183
+ ->addFieldToSelect('*')
184
+ /*
185
+ ->addFieldToSelect('transfluenttranslate_id')
186
+ ->addFieldToSelect('transfluenttranslate_store')
187
+ ->addFieldToSelect('transfluenttranslate_product')
188
+ ->addFieldToSelect('transfluenttranslate_field')
189
+ ->addFieldToSelect('transfluenttranslate_text')
190
+ */
191
+ /*
192
+ ->getData();
193
+
194
+ foreach ($pendings as $pending) {
195
+ $pend_val = $pending['transfluenttranslate_text'];
196
+ $prod_val = $product->getData($pending['transfluenttranslate_field']);
197
+
198
+ if ($pend_val != $prod_val) {
199
+ $text_id = $pending['transfluenttranslate_textid'];
200
+ $source_language = $lang_helper->getLangByCode($pending['transfluenttranslate_sourcelang']);
201
+ $token = $pending['transfluenttranslate_token'];
202
+ $translate->Text($text_id, $source_language, $prod_val, $token, 'POST');
203
+ }
204
+ }
205
+ */
206
+ }
207
+ }
app/code/community/Transfluent/Translate/Model/ProductDetail.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_ProductDetail extends Mage_Core_Model_Abstract {
8
+ private $_text_id;
9
+ private $_store;
10
+ private $_product_id;
11
+ private $_attribute_name;
12
+
13
+ public function _construct() {
14
+ parent::_construct();
15
+ }
16
+
17
+ public function SetTextId($text_id) {
18
+ if (!preg_match("/store\-([0-9]{1,})\-product\-([0-9]{1,})\-(.*)/", $text_id, $matches)) {
19
+ throw new Exception('Invalid text id');
20
+ }
21
+ $this->_text_id = $text_id;
22
+ $this->_store = $matches[1];
23
+ $this->_product_id = $matches[2];
24
+ $this->_attribute_name = $matches[3];
25
+ }
26
+
27
+ /**
28
+ * @return Mage_Catalog_Model_Product|null
29
+ */
30
+ public function Product() {
31
+ $model = Mage::getModel('catalog/product')->load($this->_product_id);
32
+ /** @var Mage_Catalog_Model_Product $model */
33
+ if ($model && $model->getId()) {
34
+ return $model;
35
+ }
36
+ return null;
37
+ }
38
+
39
+ public function OrderTitle() {
40
+ $product = $this->Product();
41
+ $title = Mage::helper('transfluenttranslate/text')->__('Product');
42
+ $title .= ' (' . Mage::helper('transfluenttranslate/text')->__($product->getResource()->getAttribute($this->_attribute_name)->getFrontend()->getLabel()) . ')';
43
+ if ($product) {
44
+ $title .= ': ' . '<a href="' . $product->getProductUrl() . '">' . $product->getName() . '</a>';
45
+ }
46
+ return $title;
47
+ }
48
+ }
app/code/community/Transfluent/Translate/Model/TagName.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_TagName extends Mage_Core_Model_Abstract {
8
+ private $_text_id;
9
+ private $_store;
10
+ private $_tag_id;
11
+
12
+ public function _construct() {
13
+ parent::_construct();
14
+ }
15
+
16
+ public function SetTextId($text_id) {
17
+ if (!preg_match("/store\-([0-9]{1,})\-tag\-([0-9]{1,})/", $text_id, $matches)) {
18
+ throw new Exception('Invalid text id');
19
+ }
20
+ $this->_text_id = $text_id;
21
+ $this->_store = $matches[1];
22
+ $this->_tag_id = $matches[2];
23
+ }
24
+
25
+ public function Tag() {
26
+ $source_tag = Mage::getModel('tag/tag')->load($this->_tag_id);
27
+ /** @var Mage_Tag_Model_Tag $source_tag */
28
+ if ($source_tag && $source_tag->getId()) {
29
+ return $source_tag;
30
+ }
31
+ return null;
32
+ }
33
+
34
+ public function OrderTitle() {
35
+ $tag = $this->Tag();
36
+ $title = Mage::helper('transfluenttranslate/text')->__('Tag');
37
+ if ($tag) {
38
+ $store = Mage::app()->getStore();
39
+ if ($tag->isAvailableInStore($store)) {
40
+ $title .= ': ' . '<a href="' . $tag->getTaggedProductsUrl() . '">' . $tag->getName() . '</a>';
41
+ } else {
42
+ $title .= ': ' . $tag->getName();
43
+ }
44
+ }
45
+ return $title;
46
+ }
47
+ }
app/code/community/Transfluent/Translate/Model/Transfluentorder.php ADDED
@@ -0,0 +1,476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Transfluent_Translate_Model_Transfluentorder
5
+ */
6
+ class Transfluent_Translate_Model_Transfluentorder extends Mage_Core_Model_Abstract {
7
+
8
+ /** const MSG_ORDER_SUCCESS successful order message */
9
+ const MSG_ORDER_SUCCESS = 'order was successful';
10
+
11
+ public function _construct() {
12
+ parent::_construct();
13
+ $this->_init('transfluenttranslate/transfluenttranslate');
14
+ }
15
+
16
+ /**
17
+ * order translation for product
18
+ *
19
+ * @param $product_id
20
+ * @param $store_id
21
+ * @param $store_from_id
22
+ * @param $level
23
+ * @param string $instructions
24
+ * @param array $translate_fields_in
25
+ * @param bool $force_translate
26
+ *
27
+ * @return bool
28
+ *
29
+ * @throws Transfluent_Translate_Exception_ETransfluentUnknownErrorBase
30
+ * @throws Exception
31
+ * @throws Transfluent_Translate_Exception_ETransfluentProductNotFoundBase
32
+ * @throws Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase
33
+ * @throws Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase
34
+ * @throws Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase
35
+ */
36
+ public function orderTranslationForProduct($product_id, $store_id, $store_from_id, $level, $instructions = '', $translate_fields_in = array(), $force_translate = false) {
37
+ set_time_limit(0);
38
+
39
+ $language_helper = Mage::helper('transfluenttranslate/languages');
40
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
41
+ $source_language = $language_helper->GetStoreLocale($store_from_id);
42
+ $source_language_id = $language_helper->getLangByCode($source_language, true);
43
+
44
+ $model = Mage::getModel('catalog/product');
45
+ /** @var Mage_Catalog_Model_Product $model */
46
+ $product = $model->setStoreId($store_from_id)->load($product_id);
47
+ /** @var Mage_Core_Model_Abstract $product */
48
+ if (!$product) {
49
+ throw new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
50
+ }
51
+ $translated_product = $model->setStoreId($store_id)->load($product->getId());
52
+ /** @var Mage_Catalog_Model_Product $translated_product */
53
+
54
+ if (!$translate_fields_in) {
55
+ $translate_fields = array();
56
+ foreach ($language_helper->DefaultProductFieldsToTranslate() AS $default_field_to_translate) {
57
+ if ($force_translate || !$translated_product->getExistsStoreValueFlag($default_field_to_translate)) {
58
+ $translate_fields[] = $default_field_to_translate;
59
+ }
60
+ }
61
+ } else {
62
+ $translate_fields = $translate_fields_in;
63
+ }
64
+
65
+ if (empty($translate_fields)) {
66
+ throw new Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase();
67
+ }
68
+
69
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
70
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
71
+ $text_hashes = array();
72
+ $keys_to_order = array();
73
+ foreach ($translate_fields AS $translate_field) {
74
+ $text_id = 'store-' . $store_id . '-product-' . $product->getId() . '-' . $translate_field;
75
+ $text_str = $product->getData($translate_field);
76
+ if ($text_str === '' || $text_str === false || is_null($text_str)) {
77
+ continue;
78
+ }
79
+ $response = $tf_client->SaveText($text_id, $source_language_id, $text_str);
80
+ if ($response && isset($response['error']['type']) && $response['error']['type'] == 'EBackendTextAlreadyUpToDate') {
81
+ // Ignore
82
+ } else if (!$response || @$response['status'] != 'OK') {
83
+ if (@$response['error']['type'] == 'EBackendSecurityViolation') {
84
+ throw new Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase();
85
+ } else if (@$response['error']['type'] == 'ENoJobs') {
86
+ throw new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
87
+ }
88
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
89
+ }
90
+ $keys_to_order[] = $text_id;
91
+ $text_hashes[$text_id] = md5($text_str);
92
+ }
93
+
94
+ $target_language = $language_helper->GetStoreLocale($store_id);
95
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
96
+ $callback_url = Mage::getUrl('transfluenttranslate/translation/save') . '?th=' . md5(Mage::getStoreConfig('transfluenttranslate/account/token'));
97
+ $context_comment = 'Text is part of product page in this webstore: ' . $product->getProductUrl() . PHP_EOL;
98
+
99
+ if ($instructions) {
100
+ $context_comment .= PHP_EOL . 'Instructions:' . PHP_EOL . '=============' . PHP_EOL . PHP_EOL;
101
+ $context_comment .= $instructions;
102
+ }
103
+
104
+ $text_ids = array();
105
+ foreach ($keys_to_order AS $text_id) {
106
+ $text_ids[] = array('id' => $text_id);
107
+ }
108
+
109
+ $response = $tf_client->TextsTranslate('Magento', $source_language_id, Mage::helper('core')->jsonEncode(array($target_language_id)), Mage::helper('core')->jsonEncode($text_ids), $context_comment, $callback_url, $level);
110
+ if ($response && @$response['status'] == 'OK') {
111
+ foreach ($keys_to_order AS $text_id) {
112
+ $order_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
113
+ $order_model->setTextId($text_id)
114
+ ->setSourceStore($store_from_id)
115
+ ->setTargetStore($store_id)
116
+ ->setSourceLanguage($source_language_id)
117
+ ->setTargetLanguage($target_language_id)
118
+ ->setLevel($level)
119
+ ->setStatus(1);
120
+ if (isset($text_hashes[$text_id])) {
121
+ $order_model->setSourceTextHash($text_hashes[$text_id]);
122
+ }
123
+ $order_model->save();
124
+ }
125
+ return true;
126
+ }
127
+
128
+ $error_msg = 'Something went wrong, the order might have not been placed properly. Please contact support@transfluent.com to resolve the issue. We apologize for the inconvenience!';
129
+ if ($response && @$response['status'] == 'ERROR' && @$response['error']['type']) {
130
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
131
+ if ($e !== null)
132
+ $error_msg = $e->getMessage();
133
+ }
134
+ throw new Exception($error_msg);
135
+ }
136
+
137
+ /**
138
+ * order translation for tag
139
+ *
140
+ * @param $tag_id
141
+ * @param $store_to_id
142
+ * @param $store_from_id
143
+ * @param $level
144
+ * @param string $instructions
145
+ *
146
+ * @return bool
147
+ *
148
+ * @throws Exception
149
+ * @throws Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase
150
+ * @throws Transfluent_Translate_Exception_ETransfluentProductNotFoundBase
151
+ * @throws Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase
152
+ * @throws Transfluent_Translate_Exception_ETransfluentUnknownErrorBase
153
+ */
154
+ public function orderTranslationForTag($tag_id, $store_to_id, $store_from_id, $level, $instructions = '') {
155
+ set_time_limit(0);
156
+ $language_helper = Mage::helper('transfluenttranslate/languages');
157
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
158
+ $source_language_code = $language_helper->GetStoreLocale($store_from_id);
159
+ $source_language_id = $language_helper->getLangByCode($source_language_code, true);
160
+
161
+ $model = Mage::getModel('tag/tag');
162
+ /** @var Mage_Tag_Model_Tag $model */
163
+ $tag = $model->setStoreId($store_from_id)->load($tag_id);
164
+ if (!$tag) {
165
+ throw new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
166
+ }
167
+ /** @var Mage_Tag_Model_Tag $tag */
168
+ $text_id = 'store-' . $store_to_id . '-tag-' . $tag->getId();
169
+ $text_to_translate = $tag->getName();
170
+ if ($text_to_translate === '' || $text_to_translate === false || is_null($text_to_translate)) {
171
+ throw new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
172
+ }
173
+
174
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
175
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
176
+ $response = $tf_client->SaveText($text_id, $source_language_id, $text_to_translate);
177
+
178
+ $backEndTextAlreadyUpToDate = ('EBackendTextAlreadyUpToDate' == $response['error']['type']);
179
+ if ($response && isset($response['error']['type']) && $backEndTextAlreadyUpToDate) {
180
+ // Ignore
181
+ } else if (!$response || 'OK' != @$response['status']) {
182
+ if (@$response['error']['type'] == 'EBackendSecurityViolation') {
183
+ throw new Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase();
184
+ } else if (@$response['error']['type'] == 'ENoJobs') {
185
+ throw new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
186
+ }
187
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
188
+ }
189
+
190
+ $target_language = $language_helper->GetStoreLocale($store_to_id);
191
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
192
+ $callback_url = Mage::getUrl('transfluenttranslate/translation/save') . '?th=' . md5(Mage::getStoreConfig('transfluenttranslate/account/token'));
193
+ $context_comment = 'The text is a product tag used in a e-commerce store.' . PHP_EOL;
194
+ // @todo FIXME: Get associated product(s) for example
195
+ if ($instructions) {
196
+ $context_comment .= $instructions;
197
+ }
198
+
199
+ $text_ids = array();
200
+ $text_ids[] = array('id' => $text_id);
201
+
202
+ $response = $tf_client->TextsTranslate('Magento', $source_language_id, Mage::helper('core')->jsonEncode(array($target_language_id)), Mage::helper('core')->jsonEncode($text_ids), $context_comment, $callback_url, $level);
203
+ if ($response && @$response['status'] == 'OK') {
204
+ foreach ($text_ids AS $row) {
205
+ $text_id = $row['id'];
206
+ $order_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
207
+ $order_model->setTextId($text_id)
208
+ ->setSourceStore($store_from_id)
209
+ ->setTargetStore($store_to_id)
210
+ ->setSourceLanguage($source_language_id)
211
+ ->setTargetLanguage($target_language_id)
212
+ ->setLevel($level)
213
+ ->setStatus(1);
214
+ if (isset($text_hashes[$text_id])) {
215
+ $order_model->setSourceTextHash($text_hashes[$text_id]);
216
+ }
217
+ $order_model->save();
218
+ }
219
+ return true;
220
+ }
221
+
222
+ if ($response && "ERROR" == @$response['status'] && @$response['error']['type']) {
223
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
224
+ if ($e) throw $e;
225
+ }
226
+
227
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
228
+ }
229
+
230
+ /**
231
+ * @param $attribute_id
232
+ * @param $store_id
233
+ * @param $translate_from_store_id
234
+ * @param $level
235
+ * @param string $instructions
236
+ * @param bool $translate_name
237
+ * @param bool $translate_values
238
+ *
239
+ * @return bool
240
+ *
241
+ * @throws Transfluent_Translate_Exception_ETransfluentUnknownErrorBase
242
+ * @throws Exception
243
+ * @throws Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase
244
+ * @throws Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase
245
+ * @throws Transfluent_Translate_Exception_ETransfluentProductNotFoundBase
246
+ * @throws Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase
247
+ */
248
+ public function orderTranslationForAttribute($attribute_id, $store_id, $translate_from_store_id, $level, $instructions = '', $translate_name = false, $translate_values = false) {
249
+ set_time_limit(0);
250
+
251
+ if (!$translate_name && !$translate_values) {
252
+ throw new Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase();
253
+ }
254
+
255
+ $language_helper = Mage::helper('transfluenttranslate/languages');
256
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
257
+ $source_language_code = $language_helper->GetStoreLocale($translate_from_store_id);
258
+ $source_language_id = $language_helper->getLangByCode($source_language_code, true);
259
+
260
+ $attribute_model = Mage::getModel('eav/entity_attribute');
261
+ /** @var Mage_Eav_Model_Entity_Attribute $attribute_model */
262
+ $attribute = $attribute_model->load($attribute_id);
263
+ if (!$attribute) {
264
+ throw new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
265
+ }
266
+
267
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
268
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
269
+
270
+ $translate_fields = array();
271
+ if ($translate_name) {
272
+ $translate_fields['store-' . $store_id . '-attribute-' . $attribute->getId()] = $attribute->getStoreLabel($translate_from_store_id);
273
+ }
274
+ if ($translate_values) {
275
+ $admin_values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')->setAttributeFilter($attribute_id)->setStoreFilter(0, false)->load();
276
+ $admin_values = array();
277
+ foreach ($admin_values_collection as $item) {
278
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
279
+ $admin_values[$item->getId()] = $item->getValue();
280
+ }
281
+ $store_values = array();
282
+ $values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')->setAttributeFilter($attribute_id)->setStoreFilter($translate_from_store_id, false)->load();
283
+ foreach ($values_collection as $item) {
284
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
285
+ $store_values[$item->getId()] = $item->getValue();
286
+ }
287
+ foreach ($admin_values AS $item_id => $item_text) {
288
+ if (isset($store_values[$item_id])) {
289
+ $item_text = $store_values[$item_id];
290
+ }
291
+ $translate_fields['store-' . $store_id . '-attribute-' . $attribute->getId() . '-option-' . $item_id] = $item_text;
292
+ }
293
+ }
294
+
295
+ $keys_to_order = array();
296
+ foreach ($translate_fields AS $text_id => $text_to_translate) {
297
+ if ($text_to_translate === '' || $text_to_translate === false || is_null($text_to_translate)) {
298
+ continue;
299
+ }
300
+ $response = $tf_client->SaveText($text_id, $source_language_id, $text_to_translate);
301
+ if ($response && isset($response['error']['type']) && $response['error']['type'] == 'EBackendTextAlreadyUpToDate') {
302
+ // Ignore
303
+ } else if (!$response || @$response['status'] != 'OK') {
304
+ if (@$response['error']['type'] == 'EBackendSecurityViolation') {
305
+ throw new Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase();
306
+ } else if (@$response['error']['type'] == 'ENoJobs') {
307
+ throw new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
308
+ }
309
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
310
+ }
311
+ $keys_to_order[] = $text_id;
312
+ }
313
+
314
+ $target_language = $language_helper->GetStoreLocale($store_id);
315
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
316
+ $callback_url = Mage::getUrl('transfluenttranslate/translation/save') . '?th=' . md5(Mage::getStoreConfig('transfluenttranslate/account/token'));
317
+ $context_comment = '';
318
+ if ($instructions) {
319
+ $context_comment .= $instructions;
320
+ }
321
+
322
+ $text_ids = array();
323
+ foreach ($keys_to_order AS $text_id) {
324
+ $text_ids[] = array('id' => $text_id);
325
+ }
326
+
327
+ $response = $tf_client->TextsTranslate('Magento', $source_language_id, Mage::helper('core')->jsonEncode(array($target_language_id)), Mage::helper('core')->jsonEncode($text_ids), $context_comment, $callback_url, $level);
328
+ if ($response && @$response['status'] == 'OK') {
329
+ foreach ($keys_to_order AS $text_id) {
330
+ $order_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
331
+ $order_model->setTextId($text_id)
332
+ ->setSourceStore($translate_from_store_id)
333
+ ->setTargetStore($store_id)
334
+ ->setSourceLanguage($source_language_id)
335
+ ->setTargetLanguage($target_language_id)
336
+ ->setLevel($level)
337
+ ->setStatus(1);
338
+ if (isset($text_hashes[$text_id])) {
339
+ $order_model->setSourceTextHash($text_hashes[$text_id]);
340
+ }
341
+ $order_model->save();
342
+ }
343
+ return true;
344
+ }
345
+
346
+ if ($response && @$response['status'] == 'ERROR' && @$response['error']['type']) {
347
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
348
+ if ($e) throw $e;
349
+ }
350
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
351
+ }
352
+
353
+ /**
354
+ * order translation for category
355
+ * @param $category_id
356
+ * @param $store_id
357
+ * @param $translate_from_store_id
358
+ * @param $level
359
+ * @param $instructions
360
+ * @param bool $translate_name
361
+ * @param bool $translate_desc
362
+ * @param bool $translate_meta
363
+ * @param bool $translate_subcat
364
+ *
365
+ * @return bool
366
+ *
367
+ * @throws Transfluent_Translate_Exception_ETransfluentUnknownErrorBase
368
+ * @throws Exception
369
+ * @throws Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase
370
+ * @throws Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase
371
+ * @throws Transfluent_Translate_Exception_ETransfluentProductNotFoundBase
372
+ * @throws Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase
373
+ */
374
+ public function orderTranslationForCategory($category_id, $store_id, $translate_from_store_id, $level, $instructions, $translate_name = false, $translate_desc = false, $translate_meta = false, $translate_subcat = false) {
375
+ set_time_limit(0);
376
+
377
+ if (!$translate_name && !$translate_desc && !$translate_meta) {
378
+ throw new Transfluent_Translate_Exception_ETransfluentProductHasNoFieldsToTranslateBase();
379
+ }
380
+
381
+ $language_helper = Mage::helper('transfluenttranslate/languages');
382
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
383
+ $source_language_code = $language_helper->GetStoreLocale($translate_from_store_id);
384
+ $source_language_id = $language_helper->getLangByCode($source_language_code, true);
385
+
386
+ $category_model = Mage::getModel('catalog/category');
387
+ /** @var Mage_Catalog_Model_Category $category_model */
388
+ $category = $category_model->setStoreId($translate_from_store_id)->load($category_id);
389
+ if (!$category) {
390
+ throw new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
391
+ }
392
+ /** @var Mage_Catalog_Model_Category $category */
393
+
394
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
395
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
396
+
397
+ if ($translate_subcat) {
398
+ $categories_to_translate = $category->getAllChildren(true);
399
+ } else {
400
+ $categories_to_translate = array($category->getId());
401
+ }
402
+ $translate_fields = array();
403
+ foreach ($categories_to_translate AS $category_id_to_translate) {
404
+ $category_to_translate = $category_model->setStoreId($translate_from_store_id)->load($category_id_to_translate);
405
+ /** @var Mage_Catalog_Model_Category $category_to_translate */
406
+ if ($translate_name) {
407
+ $translate_fields['store-' . $store_id . '-category-' . $category->getId() . '-name'] = $category->getName();
408
+ }
409
+ if ($translate_desc) {
410
+ $translate_fields['store-' . $store_id . '-category-' . $category->getId() . '-description'] = $category->getData('description');
411
+ }
412
+ if ($translate_meta) {
413
+ $translate_fields['store-' . $store_id . '-category-' . $category->getId() . '-meta-title'] = $category->getData('meta_title');
414
+ $translate_fields['store-' . $store_id . '-category-' . $category->getId() . '-meta-keywords'] = $category->getData('meta_keywords');
415
+ $translate_fields['store-' . $store_id . '-category-' . $category->getId() . '-meta-description'] = $category->getData('meta_description');
416
+ }
417
+ }
418
+
419
+ $keys_to_order = array();
420
+ foreach ($translate_fields AS $text_id => $text_to_translate) {
421
+ if ($text_to_translate === '' || $text_to_translate === false || is_null($text_to_translate)) {
422
+ continue;
423
+ }
424
+ $response = $tf_client->SaveText($text_id, $source_language_id, $text_to_translate);
425
+ if ($response && isset($response['error']['type']) && $response['error']['type'] == 'EBackendTextAlreadyUpToDate') {
426
+ // Ignore
427
+ } else if (!$response || @$response['status'] != 'OK') {
428
+ if (@$response['error']['type'] == 'EBackendSecurityViolation') {
429
+ throw new Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase();
430
+ } else if (@$response['error']['type'] == 'ENoJobs') {
431
+ throw new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
432
+ }
433
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
434
+ }
435
+ $keys_to_order[] = $text_id;
436
+ }
437
+
438
+ $target_language = $language_helper->GetStoreLocale($store_id);
439
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
440
+ $callback_url = Mage::getUrl('transfluenttranslate/translation/save') . '?th=' . md5(Mage::getStoreConfig('transfluenttranslate/account/token'));
441
+ $context_comment = '';
442
+ if ($instructions) {
443
+ $context_comment .= $instructions;
444
+ }
445
+
446
+ $text_ids = array();
447
+ foreach ($keys_to_order AS $text_id) {
448
+ $text_ids[] = array('id' => $text_id);
449
+ }
450
+
451
+ $response = $tf_client->TextsTranslate('Magento', $source_language_id, Mage::helper('core')->jsonEncode(array($target_language_id)), Mage::helper('core')->jsonEncode($text_ids), $context_comment, $callback_url, $level);
452
+ if ($response && @$response['status'] == 'OK') {
453
+ foreach ($keys_to_order AS $text_id) {
454
+ $order_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
455
+ $order_model->setTextId($text_id)
456
+ ->setSourceStore($translate_from_store_id)
457
+ ->setTargetStore($store_id)
458
+ ->setSourceLanguage($source_language_id)
459
+ ->setTargetLanguage($target_language_id)
460
+ ->setLevel($level)
461
+ ->setStatus(1);
462
+ if (isset($text_hashes[$text_id])) {
463
+ $order_model->setSourceTextHash($text_hashes[$text_id]);
464
+ }
465
+ $order_model->save();
466
+ }
467
+ return true;
468
+ }
469
+
470
+ if ($response && @$response['status'] == 'ERROR' && @$response['error']['type']) {
471
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
472
+ if ($e) throw $e;
473
+ }
474
+ throw new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
475
+ }
476
+ }
app/code/community/Transfluent/Translate/Model/Transfluenttranslate.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Model_Transfluenttranslate extends Mage_Core_Model_Abstract {
8
+
9
+ public function _construct() {
10
+ parent::_construct();
11
+ $this->_init('transfluenttranslate/transfluenttranslate');
12
+ }
13
+
14
+ /**
15
+ * getQuote model
16
+ *
17
+ * @param $store_from_id
18
+ * @param $store_to_id
19
+ * @param $level
20
+ * @param array $products
21
+ * @param $force_translate
22
+ * @param $fields_to_translate_in
23
+ * @return array
24
+ */
25
+ public function getQuote($store_from_id, $store_to_id, $level, array $products, $force_translate, $fields_to_translate_in) {
26
+
27
+ $language_helper = Mage::helper('transfluenttranslate/languages');
28
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
29
+
30
+ $source_language = $language_helper->GetStoreLocale($store_from_id);
31
+ $source_language_id = $language_helper->getLangByCode($source_language, true);
32
+
33
+ $default_source_language_id = $language_helper->DefaultSourceLanguage($store_to_id);
34
+ if ($source_language_id != $default_source_language_id) {
35
+ $language_helper->SetDefaultSourceLanguage($source_language_id);
36
+ }
37
+ $default_level = $language_helper->DefaultLevel();
38
+ if ($level != $default_level) {
39
+ $language_helper->SetDefaultLevel($level);
40
+ }
41
+
42
+ $model = Mage::getModel('catalog/product');
43
+ /** @var Mage_Catalog_Model_Product $model */
44
+
45
+ $totalWordCount = 0;
46
+ $totalCost = 0;
47
+ $priceCurrency = "";
48
+ $text = '';
49
+
50
+ foreach ($products as $productId) {
51
+
52
+ $product = $model->setStoreId($store_from_id)->load($productId);
53
+ /** @var Mage_Catalog_Model_Product $product */
54
+ if (!$product) {
55
+ continue;
56
+ }
57
+
58
+ $translate_fields = $language_helper->getTranslateFields($product, $force_translate, $store_to_id, $fields_to_translate_in);
59
+ $fields_already_translated = $language_helper->getAlreadyTranslatedFields($product, $force_translate, $store_to_id, $fields_to_translate_in);
60
+
61
+ foreach ($translate_fields AS $translate_field) {
62
+ $text .= $product->getData($translate_field) . PHP_EOL;
63
+ }
64
+ }
65
+
66
+ $target_language = $language_helper->GetStoreLocale($store_to_id);
67
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
68
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
69
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
70
+
71
+ $response = $tf_client->FreeTextWordCount($level, $text, $source_language_id, $target_language_id);
72
+
73
+ if ($response && @$response['status'] == 'OK') {
74
+ $response = $response['response'];
75
+
76
+ if (0 != $response['count']) {
77
+
78
+ $totalWordCount += $response['count'];
79
+ $totalCost += $response['price']['amount'];
80
+
81
+ if (empty($priceCurrency)) {
82
+ $priceCurrency = $response['price']['currency'];
83
+ }
84
+ }
85
+
86
+ /** @var Transfluent_Translate_Helper_Constant $constant_helper */
87
+ $constant_helper = Mage::helper('transfluenttranslate/constant');
88
+ $non_translatable_attributes = $constant_helper->getNonTranslatableAttributes();
89
+
90
+ $result = array(
91
+ 'status' => 'success',
92
+ 'wordCount' => $totalWordCount,
93
+ 'cost' => $totalCost,
94
+ 'currency' => $priceCurrency,
95
+ 'nonTranslatableAttributes' => $non_translatable_attributes,
96
+ );
97
+
98
+ $product_helper = Mage::helper('transfluenttranslate/product');
99
+ /** @var Transfluent_Translate_Helper_Product $product_helper */
100
+ $result['productAttributes'] = $product_helper->GetProductAttribute($product, $translate_fields);
101
+ $result['forceTranslate'] = $force_translate;
102
+ $result['translationFields'] = ($translate_fields) ? $translate_fields : null;
103
+ $result['fieldsAlreadyTranslated'] = ($fields_already_translated) ? $fields_already_translated : null;
104
+
105
+ return $result;
106
+
107
+ } else if ($response && @$response['status'] == 'ERROR') {
108
+ if ($response && @$response['status'] == 'ERROR' && @$response['error']['type']) {
109
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
110
+ if ($e !== null)
111
+ $error_msg = $e->getMessage();
112
+ }
113
+ }
114
+
115
+ if (empty($error_msg)) {
116
+ $e = new Transfluent_Translate_Exception_ETransfluentUnknownErrorBase();
117
+ $error_msg = $e->getMessage();
118
+ }
119
+
120
+ return array('status' => 'error', 'message' => $error_msg);
121
+ }
122
+
123
+ /**
124
+ * get text to translate for all subcategories
125
+ *
126
+ * @param Mage_Catalog_Model_Category $parent_category
127
+ * @param $translate_name
128
+ * @param $translate_desc
129
+ * @param $translate_meta
130
+ *
131
+ * @return string
132
+ */
133
+ public function getTextsToTranslateForAllSubCategories(Mage_Catalog_Model_Category $parent_category, $translate_name, $translate_desc, $translate_meta) {
134
+ $text = '';
135
+ $children = $parent_category->getAllChildren(true);
136
+ if (!$children) {
137
+ return $text;
138
+ }
139
+ $category_model = Mage::getModel('catalog/category');
140
+ /** @var Mage_Catalog_Model_Category $category_model */
141
+ foreach ($children AS $index => $category_id) {
142
+ if ($category_id == $parent_category->getId()) {
143
+ continue;
144
+ }
145
+ $category = $category_model->setStoreId($parent_category->getStoreId())->load($category_id);
146
+ /** @var Mage_Catalog_Model_Category $category */
147
+ if ($translate_name) {
148
+ $text .= $category->getName() . PHP_EOL;
149
+ }
150
+ if ($translate_desc && $category->getData('description')) {
151
+ $text .= $category->getData('description') . PHP_EOL;
152
+ }
153
+ if ($translate_meta) {
154
+ $text .= $category->getData('meta_title') . PHP_EOL;
155
+ $text .= $category->getData('meta_keywords') . PHP_EOL;
156
+ $text .= $category->getData('meta_description') . PHP_EOL;
157
+ }
158
+ }
159
+ return $text;
160
+ }
161
+
162
+ /**
163
+ * calculates quote for tags
164
+ *
165
+ * @param $tag_models
166
+ * @param $store_to_id
167
+ * @param $store_from_id
168
+ * @param $level
169
+ *
170
+ * @return array
171
+ */
172
+ public function getTagQuote($tag_models, $store_to_id, $store_from_id, $level) {
173
+ if (empty($tag_models) || empty($store_from_id) || empty($store_to_id) || empty($level)) {
174
+ return array();
175
+ }
176
+
177
+ $language_helper = Mage::helper('transfluenttranslate/languages');
178
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
179
+
180
+ $text = '';
181
+ foreach ($tag_models AS $tag_model) {
182
+ /** @var Mage_Tag_Model_Tag $tag_model */
183
+ $text .= $tag_model->getName() . PHP_EOL;
184
+ }
185
+
186
+ $target_language = $language_helper->GetStoreLocale($store_to_id);
187
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
188
+ $source_language = $language_helper->GetStoreLocale($store_from_id);
189
+ $source_language_id = $language_helper->getLangByCode($source_language, true);
190
+
191
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
192
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
193
+ $response = $tf_client->FreeTextWordCount($level, $text, $source_language_id, $target_language_id);
194
+
195
+ return $response;
196
+ }
197
+ }
app/code/community/Transfluent/Translate/controllers/Adminhtml/AccountController.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Adminhtml_AccountController extends Mage_Adminhtml_Controller_Action {
8
+ public function createAction() {
9
+ $email = $this->getRequest()->getParam('email');
10
+ $terms = $this->getRequest()->getParam('terms');
11
+
12
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
13
+ /** @var Transfluent_Translate_Model_Base_Backendclient $translate */
14
+ $response = $translate->CreateAccount($email, $terms);
15
+ print Mage::helper('core')->jsonEncode($response);
16
+ }
17
+
18
+ public function authenticateAction() {
19
+ $e = $this->getRequest()->getParam('email');
20
+ $p = $this->getRequest()->getParam('password');
21
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
22
+ /** @var Transfluent_Translate_Model_Base_Backendclient $translate */
23
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($translate->Authenticate($e, $p)));
24
+ }
25
+
26
+ public function logoutAction() {
27
+ $translate = Mage::getModel('transfluenttranslate/base_backendclient');
28
+ /** @var Transfluent_Translate_Model_Base_Backendclient $translate */
29
+ if ($translate->Logout()) {
30
+ print Mage::helper('core')->jsonEncode(array("status" => "OK"));
31
+ return;
32
+ }
33
+ print Mage::helper('core')->jsonEncode(array("status" => "ERROR"));
34
+ }
35
+ }
app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluentorderController.php ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
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()
10
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder_edit_form')
11
+ ->toHtml();
12
+ return $this;
13
+ }
14
+
15
+ public function indexAction() {
16
+ $this->_initAction();
17
+ $this->_addContent(
18
+ $this
19
+ ->getLayout()
20
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder')
21
+ );
22
+ $this->renderLayout();
23
+ }
24
+
25
+
26
+ public function orderAction() {
27
+ if (!$this->getRequest()->isPost()) {
28
+ return false;
29
+ }
30
+
31
+ $force_translate = intval($this->getRequest()->getParam('force_translate'));
32
+ $level = intval($this->getRequest()->getParam('level'));
33
+ $store_id = intval($this->getRequest()->getParam('store_to'));
34
+ $store_from_id = intval($this->getRequest()->getParam('store_from'));
35
+
36
+ $productIdJson = $this->getRequest()->getParam('product_id');
37
+ $instructions = $this->getRequest()->getParam('instructions')
38
+ ? $this->getRequest()->getParam('instructions')
39
+ : '';
40
+ $fields_to_translate_in = $this->getRequest()->getParam('fields_to_translate');
41
+ $translate_fields = array();
42
+ foreach ($fields_to_translate_in AS $field_to_translate) {
43
+ $translate_fields[] = $field_to_translate;
44
+ }
45
+
46
+ $productIds = json_decode($productIdJson);
47
+ if ($productIds === null) {
48
+ return false;
49
+ }
50
+
51
+ $status = null;
52
+
53
+ $order_model = Mage::getModel('transfluenttranslate/transfluentorder');
54
+ /** @var Transfluent_Translate_Model_Transfluentorder $order_model */
55
+
56
+ try {
57
+ foreach ($productIds as $productId) {
58
+ if (intval($productId)) {
59
+
60
+ // ordering translation for product
61
+ $status = $order_model->orderTranslationForProduct(
62
+ $productId,
63
+ $store_id,
64
+ $store_from_id,
65
+ $level,
66
+ $instructions,
67
+ $translate_fields,
68
+ $force_translate);
69
+
70
+ if (true !== $status) {
71
+ break;
72
+ }
73
+ }
74
+ }
75
+
76
+ if ($status === true) {
77
+ $this->_outputSuccessJson($order_model::MSG_ORDER_SUCCESS);
78
+ return true;
79
+ } else {
80
+ $error_msg =
81
+ Transfluent_Translate_Exception_Base
82
+ ::create('ETransfluentOrderFail')
83
+ ->getMessage();
84
+ }
85
+ } catch (Exception $e) {
86
+ $error_msg = $e->getMessage();
87
+ }
88
+
89
+ $this->_outputErrorJson($error_msg);
90
+ return false;
91
+ }
92
+
93
+ /**
94
+ * @return bool
95
+ */
96
+ public function tag_orderAction() {
97
+ if (!$this->getRequest()->isPost()) {
98
+ return false;
99
+ }
100
+
101
+ $instructions = $this->getRequest()->getParam('instructions') ? : '';
102
+ $level = intval($this->getRequest()->getParam('level'));
103
+ $store_from_id = intval($this->getRequest()->getParam('from_store'));
104
+ $store_to_id = intval($this->getRequest()->getParam('to_store'));
105
+
106
+ $tags = $this->getRequest()->getParam('tags');
107
+
108
+ if ($store_to_id === $store_from_id) {
109
+ $e = new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
110
+ $this->_outputErrorJson($e->getMessage());
111
+ return false;
112
+ }
113
+
114
+ if (empty($tags)) {
115
+ $e = new Transfluent_Translate_Exception_ETagNotFound();
116
+ $this->_outputErrorJson($e->getMessage());
117
+ return false;
118
+ }
119
+
120
+ if (!array_filter($tags, 'intval')) {
121
+ $e = new Transfluent_Translate_Exception_EInvalidTagFormat();
122
+ $this->_outputErrorJson($e->getMessage());
123
+ return false;
124
+ }
125
+
126
+ $all_ok = true;
127
+ foreach ($tags AS $tag_id) {
128
+ try {
129
+ $order_model = Mage::getModel('transfluenttranslate/transfluentorder');
130
+ /** @var Transfluent_Translate_Model_Transfluentorder $order_model */
131
+
132
+ // ordering translation for tag
133
+ $status = $order_model->orderTranslationForTag(
134
+ $tag_id,
135
+ $store_to_id,
136
+ $store_from_id,
137
+ $level,
138
+ $instructions);
139
+ if (true === $status) {
140
+ $all_ok = $all_ok && true;
141
+ continue;
142
+ }
143
+ } catch (Exception $e) {
144
+ $this->_outputErrorJson($e->getMessage());
145
+ return false;
146
+ }
147
+ $all_ok = false;
148
+ }
149
+ if ($all_ok) {
150
+ $this->_outputSuccessJson("All done! Thank you for the order.");
151
+ return true;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * order translation by attribute
157
+ */
158
+ public function attribute_orderAction() {
159
+ if (!$this->getRequest()->isPost()) {
160
+ return false;
161
+ }
162
+
163
+ $instructions = $this->getRequest()->getParam('instructions')
164
+ ? $this->getRequest()->getParam('instructions')
165
+ : '';
166
+ $translate_name = $this->getRequest()->getParam('translate_name');
167
+ $translate_values = $this->getRequest()->getParam('translate_values');
168
+ $attribute_id = intval($this->getRequest()->getParam('attribute_id'));
169
+ $level = intval($this->getRequest()->getParam('level'));
170
+ $stores = $this->getRequest()->getParam('stores');
171
+ $translate_from_store_id = intval($this->getRequest()->getParam('from_store'));
172
+
173
+ if (empty($stores)) {
174
+ $this->getResponse()
175
+ ->setBody(
176
+ '<div class="notification-global">'
177
+ . 'You did select any target languages. '
178
+ . 'Please pick at least one target language.</div>');
179
+
180
+ return false;
181
+ }
182
+ $language_helper = Mage::helper('transfluenttranslate/languages');
183
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
184
+
185
+ $source_language_id = $language_helper->GetStoreLocale($translate_from_store_id);
186
+
187
+
188
+ $output_html = "";
189
+ $all_ok = true;
190
+ foreach ($stores AS $store_id) {
191
+ /** @var Mage_Core_Model_Store $store */
192
+ $store_language = $language_helper->GetStoreLocale($store_id);
193
+ if ($source_language_id == $store_language) {
194
+ continue;
195
+ }
196
+ $output_html .= '<strong>'
197
+ . $language_helper->getLanguageNameByCode($source_language_id, true)
198
+ . '-'
199
+ . $language_helper->getLanguageNameByCode($store_language, true)
200
+ . ':</strong> ';
201
+ try {
202
+ $order_model = Mage::getModel('transfluenttranslate/transfluentorder');
203
+ /** @var Transfluent_Translate_Model_Transfluentorder $order_model */
204
+
205
+ // ordering translation for attribute
206
+ $status = $order_model->orderTranslationForAttribute(
207
+ $attribute_id,
208
+ $store_id,
209
+ $translate_from_store_id,
210
+ $level,
211
+ $instructions,
212
+ (boolean)$translate_name,
213
+ (boolean)$translate_values);
214
+ if (true === $status) {
215
+ $output_html .= '<ul class="messages"><li class="success-msg"><ul><li><span>Order placed successfully!</span></li></ul></li></ul>';
216
+ $all_ok = $all_ok && true;
217
+ continue;
218
+ }
219
+ } catch (Transfluent_Translate_Exception_Base $e) {
220
+ $this->getResponse()->setBody(
221
+ '<div class="notification-global">' . $e->getMessage() . '</div>');
222
+ } catch (Exception $e) {
223
+ $this->getResponse()->setBody(
224
+ '<div class="notification-global">' . htmlspecialchars($e->getMessage()) . '</div>');
225
+ }
226
+ $all_ok = false;
227
+ }
228
+ if ($all_ok) {
229
+ $output_html .= '<ul class="messages"><li class="success-msg"><ul><li><span>All done! Thank you for the order.</span></li></ul></li></ul>';
230
+ $this->getResponse()->setBody($output_html);
231
+ }
232
+ return $all_ok;
233
+ }
234
+
235
+
236
+ /**
237
+ * order by category
238
+ */
239
+ public function category_orderAction() {
240
+ if (!$this->getRequest()->isPost()) {
241
+ return;
242
+ }
243
+
244
+ $instructions = $this->getRequest()->getParam('instructions')
245
+ ? $this->getRequest()->getParam('instructions')
246
+ : '';
247
+ $translate_name = $this->getRequest()->getParam('translate_name');
248
+ $translate_desc = $this->getRequest()->getParam('translate_desc');
249
+ $translate_meta = $this->getRequest()->getParam('translate_meta');
250
+ $translate_subcat = $this->getRequest()->getParam('translate_subcat');
251
+ $category_id = intval($this->getRequest()->getParam('category_id'));
252
+ $level = intval($this->getRequest()->getParam('level'));
253
+ $stores = $this->getRequest()->getParam('stores');
254
+
255
+ if (empty($stores)) {
256
+ $this->getResponse()->setBody(
257
+ '<div class="notification-global">You did select any target languages. Please pick at least one target language.</div>');
258
+ return;
259
+ }
260
+ $language_helper = Mage::helper('transfluenttranslate/languages');
261
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
262
+ $translate_from_store_id = $this->getRequest()->getParam('from_store');
263
+ $source_language_id = $language_helper->GetStoreLocale($translate_from_store_id);
264
+
265
+ $all_ok = true;
266
+ $output_html = "";
267
+ foreach ($stores AS $store_id) {
268
+ /** @var Mage_Core_Model_Store $store */
269
+ $store_language = $language_helper->GetStoreLocale($store_id);
270
+ if ($source_language_id == $store_language) {
271
+ continue;
272
+ }
273
+ $output_html .= '<strong>'
274
+ . $language_helper->getLanguageNameByCode($source_language_id, true)
275
+ . '-'
276
+ . $language_helper->getLanguageNameByCode($store_language, true)
277
+ . ':</strong> ';
278
+ try {
279
+ $order_model = Mage::getModel('transfluenttranslate/transfluentorder');
280
+ /** @var Transfluent_Translate_Model_Transfluentorder $order_model */
281
+
282
+ // ordering translation for category
283
+ $status = $order_model->orderTranslationForCategory(
284
+ $category_id,
285
+ $store_id,
286
+ $translate_from_store_id,
287
+ $level,
288
+ $instructions,
289
+ (boolean)$translate_name,
290
+ (boolean)$translate_desc,
291
+ (boolean)$translate_meta,
292
+ (boolean)$translate_subcat);
293
+ if ($status === true) {
294
+ $output_html .= '<ul class="messages"><li class="success-msg"><ul><li><span>Order placed successfully!</span></li></ul></li></ul>';
295
+ $all_ok = $all_ok && true;
296
+ continue;
297
+ }
298
+ } catch (Transfluent_Translate_Exception_Base $e) {
299
+ $this->getResponse()->setBody(
300
+ '<div class="notification-global">' . $e->getMessage() . '</div>');
301
+ } catch (Exception $e) {
302
+ $this->getResponse()->setBody(
303
+ '<div class="notification-global">' . htmlspecialchars($e->getMessage()) . '</div>');
304
+ }
305
+ $all_ok = false;
306
+ }
307
+ if ($all_ok) {
308
+ $output_html .= '<ul class="messages"><li class="success-msg"><ul><li><span>All done! Thank you for the order.</span></li></ul></li></ul>';
309
+ $this->getResponse()->setBody($output_html);
310
+ }
311
+ }
312
+
313
+
314
+ public function grid_orderAction() {
315
+ if (!$this->getRequest()->isPost()) {
316
+ return;
317
+ }
318
+
319
+ $force_translate = $this->getRequest()->getParam('force_translate');
320
+ $level = $this->getRequest()->getParam('level');
321
+ $store_id = $this->getRequest()->getParam('store_to');
322
+ $store_from_id = $this->getRequest()->getParam('translate_from');
323
+ $language_helper = Mage::helper('transfluenttranslate/languages');
324
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
325
+ $products = $this->getRequest()->getParam('products');
326
+ $instructions = $this->getRequest()->getParam('instructions')
327
+ ? $this->getRequest()->getParam('instructions')
328
+ : '';
329
+
330
+ $fields_to_translate_in = $this->getRequest()->getParam('fields_to_translate');
331
+ $translate_fields = array();
332
+ if (empty($fields_to_translate_in)) {
333
+ foreach ($language_helper->DefaultProductFieldsToTranslate() AS $default_field_to_translate) {
334
+ $translate_fields[] = $default_field_to_translate;
335
+ }
336
+ } else {
337
+ $translate_fields = $fields_to_translate_in;
338
+ }
339
+
340
+ $success_count = 0;
341
+ foreach ($products as $product_id) {
342
+ try {
343
+ $order_model = Mage::getModel('transfluenttranslate/transfluentorder');
344
+ /** @var Transfluent_Translate_Model_Transfluentorder $order_model */
345
+
346
+ // ordering translation for product
347
+ $status = $order_model->orderTranslationForProduct(
348
+ $product_id,
349
+ $store_id,
350
+ $store_from_id,
351
+ $level,
352
+ $instructions,
353
+ $translate_fields,
354
+ $force_translate);
355
+
356
+ if (true === $status) {
357
+ $success_count++;
358
+ }
359
+ } catch (Transfluent_Translate_Exception_ETransfluentProductNotFoundBase $e) {
360
+ $e = new Transfluent_Translate_Exception_ETransfluentSomeSelectedProductsNotFoundBase();
361
+ Mage::getSingleton('adminhtml/session')
362
+ ->addError(Mage::helper('adminhtml')->__($e->getMessage()));
363
+ } catch (Transfluent_Translate_Exception_ETransfluentAuthenticationExpiredBase $e) {
364
+ Mage::getSingleton('adminhtml/session')
365
+ ->addError(Mage::helper('adminhtml')->__($e->getMessage()));
366
+ break;
367
+ } catch (Transfluent_Translate_Exception_Base $e) {
368
+ Mage::getSingleton('adminhtml/session')
369
+ ->addError(Mage::helper('adminhtml')->__($e->getMessage()));
370
+ } catch (Exception $e) {
371
+ Mage::getSingleton('adminhtml/session')
372
+ ->addError(($e->getMessage()
373
+ ? $e->getMessage()
374
+ : 'An unknown error occurred. Please contact Transfluent\'s support (support@transfluent.com).'));
375
+ }
376
+ }
377
+
378
+ if (count($products) == $success_count) {
379
+ Mage::getSingleton('adminhtml/session')
380
+ ->addSuccess(Mage::helper('adminhtml')->__('Thank you for the order!'));
381
+ } else if ($success_count > 0) {
382
+ Mage::getSingleton('adminhtml/session')
383
+ ->addSuccess(Mage::helper('adminhtml')->__('Some product were ordered successfully but there was issues with others. Thank you for the order!'));
384
+ } else {
385
+ Mage::getSingleton('adminhtml/session')
386
+ ->addNotice(Mage::helper('adminhtml')->__('Failed to place order! Please see details above.'));
387
+ }
388
+ }
389
+
390
+ public function getquoteAction() {
391
+ $this->_initAction();
392
+
393
+ $this->_addContent(
394
+ $this
395
+ ->getLayout()
396
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder')
397
+ ->setTemplate('transfluent/order/order.phtml')
398
+ );
399
+ $this->renderLayout();
400
+ }
401
+
402
+ public function formAction() {
403
+ $this->loadLayout();
404
+ $this->getResponse()->setBody(
405
+ $this
406
+ ->getLayout()
407
+ ->createBlock('transfluenttranslate/adminhtml_transfluentorder_edit_form')
408
+ ->toHtml()
409
+ );
410
+ }
411
+
412
+ /**
413
+ * @param $error_msg
414
+ */
415
+ private function _outputErrorJson($error_msg) {
416
+ $this->getResponse()
417
+ ->setBody(
418
+ Mage::helper('transfluenttranslate/util')
419
+ ->getErrorJson($error_msg))
420
+ ->setHeader('Content-type', 'application/json', true);
421
+ }
422
+
423
+ /**
424
+ * @param $message
425
+ */
426
+ private function _outputSuccessJson($message) {
427
+ $this->getResponse()
428
+ ->setBody(
429
+ Mage::helper('transfluenttranslate/util')
430
+ ->getSuccessJson($message))
431
+ ->setHeader('Content-type', 'application/json', true);
432
+ }
433
+ }
app/code/community/Transfluent/Translate/controllers/Adminhtml/TransfluenttranslateController.php ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_Adminhtml_TransfluenttranslateController extends Mage_Adminhtml_Controller_Action {
8
+
9
+ protected function _initAction() {
10
+ $this->loadLayout()
11
+ ->_setActiveMenu('transfluenttranslate/items')
12
+ ->_addBreadcrumb(
13
+ Mage::helper('adminhtml')->__('Items Manager'),
14
+ Mage::helper('adminhtml')->__('Item Manager'));
15
+
16
+ return $this;
17
+ }
18
+
19
+ protected function _getStoreByCode($storeCode) {
20
+ $store = Mage::app()->getStore($storeCode);
21
+ return $store->getId();
22
+ }
23
+
24
+ protected function _getAllProductIds() {
25
+ $ids = array();
26
+ $collection = Mage::getModel('catalog/product')
27
+ ->getCollection()
28
+ ->addAttributeToSelect('*');
29
+
30
+ foreach ($collection as $product) {
31
+ $ids[] = $product->getId();
32
+ }
33
+
34
+ return $ids;
35
+ }
36
+
37
+ public function indexAction() {
38
+ $this->_initAction();
39
+ $this->_addContent(
40
+ $this
41
+ ->getLayout()
42
+ ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate')
43
+ );
44
+ $this->renderLayout();
45
+ }
46
+
47
+ public function editAction() {
48
+ $id = $this->getRequest()->getParam('id');
49
+ $order = Mage::getModel('transfluenttranslate/transfluenttranslate')->load($id);
50
+
51
+ if ($order->getId()) {
52
+ Mage::register('transfluenttranslate_data', $order);
53
+ $this->loadLayout();
54
+ $this->_setActiveMenu('transfluenttranslate/items');
55
+ $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
56
+ $this
57
+ ->_addContent(
58
+ $this
59
+ ->getLayout()
60
+ ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate_edit'))
61
+ ->_addLeft(
62
+ $this
63
+ ->getLayout()
64
+ ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate_edit_tabs'));
65
+ $this->renderLayout();
66
+ } else {
67
+ Mage::getSingleton('adminhtml/session')
68
+ ->addError(Mage::helper('transfluenttranslate')->__('Item does not exist'));
69
+ $this->_redirect('*/*/');
70
+ }
71
+ }
72
+
73
+ /**
74
+ * calculate and return quote for tags
75
+ *
76
+ * @return bool
77
+ */
78
+ public function get_tag_quoteAction() {
79
+
80
+ set_time_limit(0);
81
+ if (!$this->getRequest()->isPost()) {
82
+ return false;
83
+ }
84
+
85
+ $level = intval($this->getRequest()->getParam('level'));
86
+ $store_from_id = intval($this->getRequest()->getParam('store_from_id'));
87
+ $store_to_id = intval($this->getRequest()->getParam('store_to_id'));
88
+ $tags = $this->getRequest()->getParam('tags');
89
+ $instructions = $this->getRequest()->getParam('instructions')
90
+ ?: Mage::getStoreConfig(
91
+ 'transfluenttranslate/transfluenttranslate_settings/transfluent_instructions',
92
+ $store_to_id);
93
+
94
+ if ($store_to_id === $store_from_id) {
95
+ $e = new Transfluent_Translate_Exception_ETransfluentNothingToTranslateBase();
96
+ $this->_outputErrorJson($e->getMessage());
97
+ return false;
98
+ }
99
+
100
+ if (empty($tags) || !array_filter($tags, 'intval')) {
101
+ $e = new Transfluent_Translate_Exception_ETransfluentInvalidInputTagsBase();
102
+ $this->_outputErrorJson($e->getMessage());
103
+ return false;
104
+ }
105
+
106
+ $tag_helper = Mage::helper('transfluenttranslate/tag');
107
+ /** @var Transfluent_Translate_Helper_Tag $tag_helper */
108
+ $tag_models = $tag_helper->getTags($tags, $store_from_id);
109
+
110
+ if (empty($tag_models)) {
111
+ $e = new Transfluent_Translate_Exception_ETagNotFound();
112
+ $this->_outputErrorJson($e->getMessage());
113
+ return false;
114
+ }
115
+
116
+ $translate_model = new Transfluent_Translate_Model_Transfluenttranslate();
117
+ $getQuoteResponse = $translate_model
118
+ ->getTagQuote($tag_models, $store_to_id, $store_from_id, $level);
119
+
120
+ if (empty($getQuoteResponse) || !array_key_exists('status', $getQuoteResponse)) {
121
+ $e = new Transfluent_Translate_Exception_ETransfluentUnknownBackendResponseBase();
122
+ $this->_outputErrorJson($e->getMessage());
123
+ return false;
124
+ }
125
+
126
+ $error_msg = null;
127
+ if ('OK' == $getQuoteResponse['status']) {
128
+ $getQuoteResponse = $getQuoteResponse['response'];
129
+
130
+ $result = array(
131
+ 'status' => 'success',
132
+ 'wordCount' => $getQuoteResponse['count'],
133
+ 'cost' => $getQuoteResponse['price']['amount'],
134
+ 'currency' => $getQuoteResponse['price']['currency'],
135
+ 'instruction' => Mage::helper('core')->quoteEscape($instructions)
136
+ );
137
+
138
+ $this->_outputSuccessJson($result);
139
+ return true;
140
+ } else if ('ERROR' == $getQuoteResponse['status']) {
141
+ if (array_key_exists('type', $getQuoteResponse['error'])) {
142
+ $e = Transfluent_Translate_Exception_Base::create($getQuoteResponse['error']['type']);
143
+ if ($e !== null)
144
+ $error_msg = $e->getMessage();
145
+ }
146
+ }
147
+
148
+ $e = new Transfluent_Translate_Exception_ETransfluentUnknownErrorNoEstimateBase();
149
+ $error_msg = $error_msg ? : $e->getMessage();
150
+ $this->_outputErrorJson($error_msg);
151
+ return false;
152
+ }
153
+
154
+ public function get_category_quoteAction() {
155
+ set_time_limit(0);
156
+ if (!$this->getRequest()->isPost()) {
157
+ return;
158
+ }
159
+ $translate_name = $this->getRequest()->getParam('translate_name');
160
+ $translate_desc = $this->getRequest()->getParam('translate_desc');
161
+ $translate_meta = $this->getRequest()->getParam('translate_meta');
162
+ $translate_subcat = $this->getRequest()->getParam('translate_subcat');
163
+ if (!$translate_name && !$translate_desc && !$translate_meta) {
164
+ $error_msg = 'You did not select anything to be translated. Pick either attribute name, description or meta data to be translated.';
165
+ }
166
+ $level = intval($this->getRequest()->getParam('level'));
167
+ $stores = $this->getRequest()->getParam('stores');
168
+ if (empty($stores) || !is_array($stores)) {
169
+ $error_msg = 'You did select any target languages. Please pick at least one target language.';
170
+ $stores = array();
171
+ }
172
+ $language_helper = Mage::helper('transfluenttranslate/languages');
173
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
174
+ $translate_from_store_id = $this->getRequest()->getParam('from_store');
175
+ $source_language_id = $language_helper->GetStoreLocale($translate_from_store_id);
176
+ $category_id = $this->getRequest()->getParam('category_id');
177
+
178
+ $category_model = Mage::getModel('catalog/category');
179
+ /** @var Mage_Catalog_Model_Category $category_model */
180
+ $category = $category_model->setStoreId($translate_from_store_id)->load($category_id);
181
+ if (!$category) {
182
+ $error_msg = 'Could not find category to translate!';
183
+ }
184
+ /** @var Mage_Catalog_Model_Category $category */
185
+
186
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
187
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
188
+ $text = '';
189
+ if ($translate_name) {
190
+ $text .= $category->getName() . PHP_EOL;
191
+ }
192
+ if ($translate_desc && $category->getData('description')) {
193
+ $text .= $category->getData('description') . PHP_EOL;
194
+ }
195
+ if ($translate_meta) {
196
+ $text .= $category->getData('meta_title') . PHP_EOL;
197
+ $text .= $category->getData('meta_keywords') . PHP_EOL;
198
+ $text .= $category->getData('meta_description') . PHP_EOL;
199
+ }
200
+ if ($translate_subcat) {
201
+ $translate_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
202
+ /** @var Transfluent_Translate_Model_Transfluenttranslate $translate_model */
203
+
204
+ $text .= $translate_model->getTextsToTranslateForAllSubCategories(
205
+ $category,
206
+ $translate_name,
207
+ $translate_desc,
208
+ $translate_meta);
209
+ }
210
+
211
+ $total_words = 0;
212
+ $total_price = '0';
213
+ $price_currency = 'EUR';
214
+ $output_html = "";
215
+ foreach ($stores AS $store_id) {
216
+ /** @var Mage_Core_Model_Store $store */
217
+ $store_language = $language_helper->GetStoreLocale($store_id);
218
+ $output_html .= '<strong>'
219
+ . $language_helper->getLanguageNameByCode($source_language_id, true)
220
+ . '-'
221
+ . $language_helper->getLanguageNameByCode($store_language, true)
222
+ . ':</strong> ';
223
+ if ($source_language_id == $store_language) {
224
+ $output_html .= 'Unfortunately proof-reading is not yet supported!<br>';
225
+ continue;
226
+ }
227
+ $response = $tf_client->FreeTextWordCount(
228
+ $level,
229
+ $text,
230
+ $language_helper->getLangByCode($source_language_id, true),
231
+ $language_helper->getLangByCode($store_language, true));
232
+ if ($response && @$response['status'] == 'OK') {
233
+ $response = $response['response'];
234
+ $output_html .= $response['count']
235
+ . ' words to translate. Translation costs '
236
+ . $response['price']['amount']
237
+ . $response['price']['currency']
238
+ . '.<br>';
239
+ $price_currency = $response['price']['currency'];
240
+ $locale_details = localeconv();
241
+ $total_price = bcadd(
242
+ $total_price,
243
+ str_replace(
244
+ '.',
245
+ $locale_details['decimal_point'],
246
+ (string)$response['price']['amount']),
247
+ 2);
248
+ $total_words += $response['count'];
249
+ continue;
250
+ } else if ($response && @$response['status'] == 'ERROR') {
251
+ switch (@$response['error']['type']) {
252
+ case 'ELanguagePairNotSupportedException':
253
+ $e = new Transfluent_Translate_Exception_ELanguagePairNotSupported();
254
+ $output_html .= $e->getMessage();
255
+ continue;
256
+ }
257
+ $output_html .= 'Failed to estimate. Please try again. If problem persist, please contact our support.<br>';
258
+ }
259
+ }
260
+ if (!isset($error_msg) || !$error_msg) {
261
+ $output_html .= '<strong>Total:</strong> '
262
+ . $total_words
263
+ . ' words, '
264
+ . $total_price
265
+ . $price_currency
266
+ . '<br>';
267
+ $output_html .= ' - <a href="#" onclick="$(\'tf_translate_form_instructions\').toggle(); return false;">Instructions</a><br>';
268
+ $instructions = $this->getRequest()->getParam('instructions')
269
+ ? $this->getRequest()->getParam('instructions')
270
+ : Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_instructions');
271
+ $instructions = $instructions ? $instructions : '';
272
+ $output_html .= '<div id="tf_translate_form_instructions" style="display: none;"><textarea id="tf_translate_instructions_txt" name="instructions" cols=60 rows=4>' . Mage::helper('core')->quoteEscape($instructions) . '</textarea><br></div>';
273
+ $output_html .= '<br>';
274
+ $output_html .= '<span id="quote_action_buttons_container">';
275
+ $output_html .= '<button title="Order" type="button" id="tf_place_order_btn" class="scalable save" onclick="OrderTranslation(this); return false;"><span><span><span>Order translation</span></span></span></button> ';
276
+ $output_html .= '<button title="Cancel" type="button" class="scalable cancel" onclick="ResetEstimation();" style=""><span><span><span>Cancel</span></span></span></button>';
277
+ $output_html .= '</span>';
278
+ } else {
279
+ $error_msg = (isset($error_msg)
280
+ ? $error_msg
281
+ : 'An error occurred and costs could not be estimated at the moment. Please try again!');
282
+ $output_html .= '<div class="notification-global">' . $error_msg . '</div><br>';
283
+ $output_html .= '<button title="OK" type="button" class="scalable back" onclick="ResetEstimation();" style=""><span><span><span>OK</span></span></span></button>';
284
+ }
285
+
286
+ $this->getResponse()->setBody($output_html);
287
+ }
288
+
289
+ public function get_attribute_quoteAction() {
290
+ set_time_limit(0);
291
+ if (!$this->getRequest()->isPost()) {
292
+ return;
293
+ }
294
+ $translate_name = $this->getRequest()->getParam('translate_name');
295
+ $translate_values = $this->getRequest()->getParam('translate_values');
296
+ if (!$translate_name && !$translate_values) {
297
+ $error_msg = 'You did not select anything to be translated. Pick either attribute name, options or both to be translated.';
298
+ }
299
+ $level = $this->getRequest()->getParam('level');
300
+ $stores = $this->getRequest()->getParam('stores');
301
+ if (empty($stores) || !is_array($stores)) {
302
+ $error_msg = 'You did select any target languages. Please pick at least one target language.';
303
+ $stores = array();
304
+ }
305
+ $language_helper = Mage::helper('transfluenttranslate/languages');
306
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
307
+ $translate_from_store_id = $this->getRequest()->getParam('from_store');
308
+ $source_language_id = $language_helper->GetStoreLocale($translate_from_store_id);
309
+ $attribute_id = $this->getRequest()->getParam('attribute_id');
310
+
311
+ $attribute_model = Mage::getModel('eav/entity_attribute');
312
+ /** @var Mage_Eav_Model_Entity_Attribute $attribute_model */
313
+ $attribute = $attribute_model->load($attribute_id);
314
+ if (!$attribute) {
315
+ $error_msg = 'Could not find attribute to translate!';
316
+ }
317
+
318
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
319
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
320
+ $text = '';
321
+ if ($translate_name) {
322
+ $text .= $attribute->getStoreLabel($translate_from_store_id) . PHP_EOL;
323
+ }
324
+ if ($translate_values) {
325
+ $admin_values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
326
+ ->setAttributeFilter($attribute_id)
327
+ ->setStoreFilter(0, false)
328
+ ->load();
329
+ $admin_values = array();
330
+ foreach ($admin_values_collection as $item) {
331
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
332
+ $admin_values[$item->getId()] = $item->getValue();
333
+ }
334
+ $store_values = array();
335
+ $values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
336
+ ->setAttributeFilter($attribute_id)
337
+ ->setStoreFilter($translate_from_store_id, false)
338
+ ->load();
339
+ foreach ($values_collection as $item) {
340
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
341
+ $store_values[$item->getId()] = $item->getValue();
342
+ }
343
+ foreach ($admin_values AS $item_id => $item_text) {
344
+ if (isset($store_values[$item_id])) {
345
+ $text .= $store_values[$item_id] . PHP_EOL;
346
+ continue;
347
+ }
348
+ $text .= $item_text . PHP_EOL;
349
+ }
350
+ }
351
+
352
+ $total_words = 0;
353
+ $total_price = '0';
354
+ $price_currency = 'EUR';
355
+ $output_html = "";
356
+ foreach ($stores AS $store_id) {
357
+ /** @var Mage_Core_Model_Store $store */
358
+ $store_language = $language_helper->GetStoreLocale($store_id);
359
+ $output_html .= '<strong>'
360
+ . $language_helper->getLanguageNameByCode($source_language_id, true)
361
+ . '-'
362
+ . $language_helper->getLanguageNameByCode($store_language, true)
363
+ . ':</strong> ';
364
+ if ($source_language_id == $store_language) {
365
+ $output_html .= 'Unfortunately proof-reading is not yet supported!<br>';
366
+ continue;
367
+ }
368
+ $response = $tf_client->FreeTextWordCount(
369
+ $level,
370
+ $text,
371
+ $language_helper->getLangByCode($source_language_id, true),
372
+ $language_helper->getLangByCode($store_language, true));
373
+ if ($response && @$response['status'] == 'OK') {
374
+ $response = $response['response'];
375
+ $output_html .= $response['count']
376
+ . ' words to translate. Translation costs '
377
+ . $response['price']['amount']
378
+ . $response['price']['currency']
379
+ . '.<br>';
380
+ $price_currency = $response['price']['currency'];
381
+ $locale_details = localeconv();
382
+ $total_price = bcadd(
383
+ $total_price,
384
+ str_replace(
385
+ '.',
386
+ $locale_details['decimal_point'],
387
+ (string)$response['price']['amount']),
388
+ 2);
389
+ $total_words += $response['count'];
390
+ continue;
391
+ } else if ($response && @$response['status'] == 'ERROR') {
392
+ switch (@$response['error']['type']) {
393
+ case 'ELanguagePairNotSupportedException':
394
+ $e = new Transfluent_Translate_Exception_ELanguagePairNotSupported();
395
+ $output_html .= $e->getMessage();
396
+ continue;
397
+ }
398
+ $output_html .= 'Failed to estimate. Please try again. If problem persist, please contact our support.<br>';
399
+ }
400
+ }
401
+ if (!isset($error_msg) || !$error_msg) {
402
+ $output_html .= '<strong>Total:</strong> '
403
+ . $total_words
404
+ . ' words, '
405
+ . $total_price
406
+ . $price_currency
407
+ . '<br>';
408
+ $output_html .= ' - <a href="#" onclick="$(\'tf_translate_form_instructions\').toggle(); return false;">Instructions</a><br>';
409
+ $instructions = $this->getRequest()->getParam('instructions')
410
+ ? $this->getRequest()->getParam('instructions')
411
+ : Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_instructions');
412
+ $instructions = $instructions ? $instructions : '';
413
+ $output_html .= '<div id="tf_translate_form_instructions" style="display: none;"><textarea id="tf_translate_instructions_txt" name="instructions" cols=60 rows=4>' . Mage::helper('core')->quoteEscape($instructions) . '</textarea><br></div>';
414
+ $output_html .= '<br>';
415
+ $output_html .= '<span id="quote_action_buttons_container">';
416
+ $output_html .= '<button title="Order" type="button" id="tf_place_order_btn" class="scalable save" onclick="OrderTranslation(this); return false;"><span><span><span>Order translation</span></span></span></button> ';
417
+ $output_html .= '<button title="Cancel" type="button" class="scalable cancel" onclick="ResetEstimation();" style=""><span><span><span>Cancel</span></span></span></button>';
418
+ $output_html .= '</span>';
419
+ } else {
420
+ $error_msg = (isset($error_msg)
421
+ ? $error_msg
422
+ : 'An error occurred and costs could not be estimated at the moment. Please try again!');
423
+ $output_html .= '<div class="notification-global">' . $error_msg . '</div><br>';
424
+ $output_html .= '<button title="OK" type="button" class="scalable back" onclick="ResetEstimation();" style=""><span><span><span>OK</span></span></span></button>';
425
+ }
426
+
427
+ $this->getResponse()->setBody($output_html);
428
+ }
429
+
430
+ /**
431
+ * calculates quote
432
+ */
433
+ public function get_quoteAction() {
434
+ set_time_limit(0);
435
+ if (!$this->getRequest()->isPost()) {
436
+ return false;
437
+ }
438
+
439
+ $force_translate = intval($this->getRequest()->getParam('force_translate'));
440
+ $level = intval($this->getRequest()->getParam('level'));
441
+ $store_from_id = intval($this->getRequest()->getParam('store_from'));
442
+ $store_to_id = intval($this->getRequest()->getParam('store_to'));
443
+ $fields_to_translate_in = $this->getRequest()->getParam('fields_to_translate');
444
+ $product_id_json = $this->getRequest()->getParam('product_id');
445
+ $instructions = $this->getRequest()->getParam('instructions');
446
+
447
+ if (empty($fields_to_translate_in)) {
448
+ $fields_to_translate_in = null;
449
+ }
450
+
451
+ if (empty($instructions)) {
452
+ $instructions = Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_instructions', $store_to_id);
453
+ }
454
+
455
+ $products = json_decode($product_id_json);
456
+ if ($products === null) {
457
+ $this->_outputErrorJson('Input-product-ID(s) format is invalid!');
458
+ return false;
459
+ }
460
+
461
+ if (empty($products)) {
462
+ $e = new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
463
+ $this->_outputErrorJson($e->getMessage());
464
+ return false;
465
+ }
466
+
467
+ $language_helper = Mage::helper('transfluenttranslate/languages');
468
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
469
+
470
+ $source_language = $language_helper->GetStoreLocale($store_from_id);
471
+ $source_language_id = $language_helper->getLangByCode($source_language, true);
472
+
473
+ $default_source_language_id = $language_helper->DefaultSourceLanguage($store_to_id);
474
+ if ($source_language_id != $default_source_language_id) {
475
+ $language_helper->SetDefaultSourceLanguage($source_language_id);
476
+ }
477
+ $default_level = $language_helper->DefaultLevel();
478
+ if ($level != $default_level) {
479
+ $language_helper->SetDefaultLevel($level);
480
+ }
481
+
482
+ $translate_model = Mage::getModel('transfluenttranslate/transfluenttranslate');
483
+ /** @var Transfluent_Translate_Model_Transfluenttranslate $translate_model */
484
+
485
+ // quote calculation by model
486
+ $result = $translate_model->getQuote(
487
+ $store_from_id,
488
+ $store_to_id,
489
+ $level,
490
+ $products,
491
+ $force_translate,
492
+ $fields_to_translate_in);
493
+
494
+ if (!empty($result) && is_array($result)) {
495
+ $result['instruction'] = Mage::helper('core')->quoteEscape($instructions);
496
+ $this->_outputSuccessJson($result);
497
+ return true;
498
+ }
499
+ return false;
500
+ }
501
+
502
+ public function gridAction() {
503
+ $this->loadLayout();
504
+ $this->getResponse()->setBody(
505
+ $this
506
+ ->getLayout()
507
+ ->createBlock('transfluenttranslate/adminhtml_transfluenttranslate_grid')
508
+ ->toHtml()
509
+ );
510
+ }
511
+
512
+ /**
513
+ * @param $error_msg
514
+ */
515
+ private function _outputErrorJson($error_msg) {
516
+ $this->getResponse()
517
+ ->setBody(
518
+ Mage::helper('transfluenttranslate/util')
519
+ ->getErrorJson($error_msg))
520
+ ->setHeader('Content-type', 'application/json', true);
521
+ }
522
+
523
+ /**
524
+ * @param $message
525
+ */
526
+ private function _outputSuccessJson($message) {
527
+ $this->getResponse()
528
+ ->setBody(json_encode($message))
529
+ ->setHeader('Content-type', 'application/json', true);
530
+ }
531
+ }
532
+
app/code/community/Transfluent/Translate/controllers/TranslationController.php ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
5
+ * Author: coders@transfluent.com
6
+ */
7
+ class Transfluent_Translate_TranslationController extends Mage_Core_Controller_Front_Action {
8
+ private $_handlers = array(
9
+ "/store\-([0-9]{1,})\-tag\-([0-9]{1,})/" => '_saveTagName',
10
+ "/store\-([0-9]{1,})\-product\-([0-9]{1,})\-(.*)/" => '_saveProductDetails',
11
+ "/store\-([0-9]{1,})\-attribute\-([0-9]{1,})\-option\-([0-9]{1,})/" => '_saveAttributeOptions',
12
+ "/store\-([0-9]{1,})\-attribute\-([0-9]{1,})/" => '_saveAttributeName',
13
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-name/" => '_saveCategoryName',
14
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-description/" => '_saveCategoryDescription',
15
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-title/" => '_saveCategoryMetaTitle',
16
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-keywords/" => '_saveCategoryMetaKeywords',
17
+ "/store\-([0-9]{1,})\-category\-([0-9]{1,})\-meta\-description/" => '_saveCategoryMetaDescription',
18
+ );
19
+
20
+ public function saveAction() {
21
+ try {
22
+ $this->_validateToken();
23
+
24
+ list($payload, $text_id) = $this->_parseRequest();
25
+ $status = $this->_handleRequest($text_id, $payload);
26
+
27
+ if ($status === true) {
28
+ $response = array('status' => 'OK');
29
+ } else {
30
+ $response = array(
31
+ 'status' => 'ERROR',
32
+ 'error' => array(
33
+ 'type' => 'N/A',
34
+ 'message' => 'An unexpected error occurred.'
35
+ )
36
+ );
37
+ }
38
+ } catch (Exception $e) {
39
+ $response = array(
40
+ 'status' => 'ERROR',
41
+ 'error' => array(
42
+ 'type' => get_class($e),
43
+ 'message' => $e->getMessage()
44
+ )
45
+ );
46
+ $status = false;
47
+ }
48
+
49
+ $this->getResponse()
50
+ ->setBody(
51
+ Mage::helper('core')->jsonEncode($response))
52
+ ->setHttpResponseCode($status === true ? 200 : 500)
53
+ ->setHeader('Content-type', 'application/json', true);
54
+ }
55
+
56
+
57
+ private function _validateToken() {
58
+ $token_str = Mage::getStoreConfig('transfluenttranslate/account/token');
59
+ if (!$token_str) {
60
+ throw new Transfluent_Translate_Exception_EUnauthorized();
61
+ }
62
+ $token_hash = md5($token_str);
63
+ $token_hash_in = $this->getRequest()->getParam('th');
64
+ if (!$token_hash_in || $token_hash_in != $token_hash) {
65
+ throw new Transfluent_Translate_Exception_EUnauthorized();
66
+ }
67
+ }
68
+
69
+ private function _parseRequest() {
70
+ $request_body = file_get_contents('php://input');
71
+ $payload = Mage::helper('core')->jsonDecode($request_body, true);
72
+ if (!isset($payload)) {
73
+ throw new Transfluent_Translate_Exception_EInvalidInput();
74
+ }
75
+ if (@$payload['group_id'] != 'Magento') {
76
+ throw new Transfluent_Translate_Exception_EInvalidJob();
77
+ }
78
+ $text_id = $payload['text_id'];
79
+ return array($payload, $text_id);
80
+ }
81
+
82
+ private function _handleRequest($text_id, $payload) {
83
+ $status = null;
84
+ foreach ($this->_handlers AS $pattern => $method_to_call) {
85
+ $matches = null;
86
+ if (preg_match($pattern, $text_id, $matches)) {
87
+ $status = call_user_func(
88
+ array($this, $method_to_call),
89
+ $matches,
90
+ $payload,
91
+ $text_id);
92
+ break;
93
+ }
94
+ }
95
+ if ($status === null)
96
+ throw new Transfluent_Translate_Exception_ETransfluentInvalidInputTagsBase();
97
+
98
+ return $status;
99
+ }
100
+
101
+ private function _saveCategoryName($matches, $payload, $text_id) {
102
+ $store_id = $matches[1];
103
+ $category_id = $matches[2];
104
+
105
+ $translated_str = trim($payload['text']);
106
+ return $this->_updateCategoryDetail(
107
+ $category_id,
108
+ $store_id,
109
+ 'name',
110
+ $translated_str,
111
+ $text_id,
112
+ $payload);
113
+ }
114
+
115
+ private function _saveCategoryDescription($matches, $payload, $text_id) {
116
+ $store_id = $matches[1];
117
+ $category_id = $matches[2];
118
+
119
+ $translated_str = trim($payload['text']);
120
+ return $this->_updateCategoryDetail(
121
+ $category_id,
122
+ $store_id,
123
+ 'description',
124
+ $translated_str,
125
+ $text_id,
126
+ $payload);
127
+ }
128
+
129
+ private function _saveCategoryMetaTitle($matches, $payload, $text_id) {
130
+ $store_id = $matches[1];
131
+ $category_id = $matches[2];
132
+
133
+ $translated_str = trim($payload['text']);
134
+ return $this->_updateCategoryDetail(
135
+ $category_id,
136
+ $store_id,
137
+ 'meta_title',
138
+ $translated_str,
139
+ $text_id,
140
+ $payload);
141
+ }
142
+
143
+ private function _saveCategoryMetaKeywords($matches, $payload, $text_id) {
144
+ $store_id = $matches[1];
145
+ $category_id = $matches[2];
146
+
147
+ $translated_str = trim($payload['text']);
148
+ return $this->_updateCategoryDetail(
149
+ $category_id,
150
+ $store_id,
151
+ 'meta_keywords',
152
+ $translated_str,
153
+ $text_id,
154
+ $payload);
155
+ }
156
+
157
+ private function _saveCategoryMetaDescription($matches, $payload, $text_id) {
158
+ $store_id = $matches[1];
159
+ $category_id = $matches[2];
160
+
161
+ $translated_str = trim($payload['text']);
162
+ return $this->_updateCategoryDetail(
163
+ $category_id,
164
+ $store_id,
165
+ 'meta_description',
166
+ $translated_str,
167
+ $text_id,
168
+ $payload);
169
+ }
170
+
171
+ private function _updateCategoryDetail($category_id, $store_id, $key, $value, $text_id, $payload) {
172
+ $category_model = Mage::getModel('catalog/category');
173
+ /** @var Mage_Catalog_Model_Category $category_model */
174
+ $category = $category_model->setStoreId($store_id)->load($category_id);
175
+ if (!$category || !$category->getId()) {
176
+ throw new Transfluent_Translate_Exception_ETransfluentProductNotFoundBase();
177
+ }
178
+ /** @var Mage_Catalog_Model_Category $category */
179
+ $category->setData($key, $value);
180
+ $category->save();
181
+ return $this->_updateOrder($store_id, $text_id, $payload['level']);
182
+ }
183
+
184
+ private function _saveTagName($matches, $payload, $text_id) {
185
+ $store_id = $matches[1];
186
+ $tag_id = $matches[2];
187
+
188
+ $translated_tag_str = trim($payload['text']);
189
+
190
+ $source_tag = Mage::getModel('tag/tag')->load($tag_id);
191
+ /** @var Mage_Tag_Model_Tag $source_tag */
192
+ /** @var Mage_Tag_Model_Tag $model */
193
+ if (isset($payload['previous_text']) && $payload['previous_text']) {
194
+ $model = Mage::getModel('tag/tag')
195
+ ->setStoreId($store_id)
196
+ ->loadByName($payload['previous_text']);
197
+ Mage::register('isSecureArea', true);
198
+ $model->delete();
199
+ Mage::unregister('isSecureArea');
200
+ }
201
+
202
+ $model = Mage::getModel('tag/tag')
203
+ ->setStoreId($store_id)
204
+ ->loadByName($translated_tag_str);
205
+ $was_added = false;
206
+ if ($model && $model->getId() && $model->isAvailableInStore($store_id)) {
207
+ return true;
208
+ } else if (!$model->getId()) {
209
+ $model->setStoreId($store_id);
210
+ $model->setFirstStoreId($store_id);
211
+ $was_added = true;
212
+ $model->setStatus($source_tag->getStatus());
213
+ $model->setAddBasePopularity($source_tag->getAddBasePopularity());
214
+ if ($source_tag->getRatio()) {
215
+ $model->setRatio($source_tag->getRatio());
216
+ }
217
+ }
218
+ $model->setName($translated_tag_str);
219
+ $model->save();
220
+
221
+ if ($was_added) {
222
+ foreach ($source_tag->getRelatedProductIds() AS $product_id) {
223
+ $model->saveRelation($product_id, null, $store_id);
224
+ }
225
+ }
226
+ return $this->_updateOrder($store_id, $text_id, $payload['level']);
227
+ }
228
+
229
+ private function _saveAttributeName($matches, $payload, $text_id) {
230
+ $store_id = $matches[1];
231
+ $attribute_id = $matches[2];
232
+
233
+ $attribute_model = Mage::getModel('eav/entity_attribute');
234
+ /** @var Mage_Eav_Model_Entity_Attribute $attribute_model */
235
+ $attribute = $attribute_model->load($attribute_id);
236
+ if (!$attribute) {
237
+ throw new Exception('Attribute not found!');
238
+ }
239
+ $store_labels = $attribute->getStoreLabels();
240
+ $store_labels[$store_id] = $payload['text'];
241
+ $attribute->setData('store_labels', $store_labels);
242
+ $attribute->save();
243
+
244
+ Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
245
+ return $this->_updateOrder($store_id, $text_id, $payload['level']);
246
+ }
247
+
248
+ private function _saveAttributeOptions($matches, $payload, $text_id) {
249
+ $store_id = $matches[1];
250
+ $attribute_id = $matches[2];
251
+ $option_id = $matches[3];
252
+
253
+
254
+ $attribute_model = Mage::getModel('catalog/resource_eav_attribute');
255
+ $attribute_model->load($attribute_id);
256
+
257
+ $values_by_store = array();
258
+ $stores = Mage::app()->getStores();
259
+ $values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
260
+ ->setAttributeFilter($attribute_id)
261
+ ->setStoreFilter(0, false)
262
+ ->load();
263
+ foreach ($values_collection as $item) {
264
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
265
+ if ($item->getId() != $option_id) {
266
+ continue;
267
+ }
268
+ $values_by_store[0] = $item->getValue();
269
+ }
270
+ foreach ($stores AS $store) {
271
+ /** @var Mage_Core_Model_Store $store */
272
+ $values_collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
273
+ ->setAttributeFilter($attribute_id)
274
+ ->setStoreFilter($store->getId(), false)
275
+ ->load();
276
+ foreach ($values_collection as $item) {
277
+ /** @var Mage_Eav_Model_Entity_Attribute_Option $item */
278
+ if ($item->getId() != $option_id) {
279
+ continue;
280
+ }
281
+ $values_by_store[$store->getId()] = $item->getValue();
282
+ }
283
+ }
284
+ $data = array();
285
+ foreach ($values_by_store AS $cur_store_id => $label) {
286
+ if (!$label) {
287
+ continue;
288
+ }
289
+ $data['option']['value'][$option_id][$cur_store_id] = $label;
290
+ }
291
+ $data['option']['value'][$option_id][$store_id] = $payload['text'];
292
+ $attribute_model->addData($data);
293
+ $attribute_model->save();
294
+
295
+ Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
296
+ return $this->_updateOrder($store_id, $text_id, $payload['level']);
297
+ }
298
+
299
+ private function _saveProductDetails($matches, $payload, $text_id) {
300
+ $store_id = $matches[1];
301
+ $product_id = $matches[2];
302
+ $field_name = $matches[3];
303
+
304
+ $product_action = Mage::getSingleton('catalog/product_action');
305
+ /** @var Mage_Catalog_Model_Product_Action $product_action */
306
+ $product_action->updateAttributes(
307
+ array($product_id),
308
+ array((string)$field_name => $payload['text'] ? : ''),
309
+ $store_id);
310
+
311
+ return $this->_updateOrder($store_id, $text_id, $payload['level']);
312
+ }
313
+
314
+ private function _updateOrder($store_id, $text_id, $level) {
315
+ $product_helper = Mage::helper('transfluenttranslate/product');
316
+ /** @var Transfluent_Translate_Helper_Product $product_helper */
317
+ $order = $product_helper->GetOrder($store_id, $text_id, $level);
318
+ if ($order && $order->count() == 1) {
319
+ /** @var Transfluent_Translate_Model_Mysql4_Transfluenttranslate_Collection $order */
320
+ $order->setDataToAll('status', 2);
321
+ $order->save();
322
+ } else {
323
+ throw new Transfluent_Translate_Exception_EFailedToUpdateOrder();
324
+ }
325
+ return true;
326
+ }
327
+ }
328
+
app/code/community/Transfluent/Translate/etc/config.xml ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Transfluent_Translate>
5
+ <version>1.2.0</version>
6
+ </Transfluent_Translate>
7
+ </modules>
8
+
9
+ <frontend>
10
+ <routers>
11
+ <transfluenttranslate>
12
+ <use>standard</use>
13
+
14
+ <args>
15
+ <module>Transfluent_Translate</module>
16
+ <frontName>Translate</frontName>
17
+ </args>
18
+ </transfluenttranslate>
19
+ </routers>
20
+ </frontend>
21
+
22
+ <global>
23
+ <models>
24
+ <transfluenttranslate>
25
+ <class>Transfluent_Translate_Model</class>
26
+ <resourceModel>transfluenttranslate_mysql4</resourceModel>
27
+ </transfluenttranslate>
28
+ <transfluenttranslate_mysql4>
29
+ <class>Transfluent_Translate_Model_Mysql4</class>
30
+ <entities>
31
+ <transfluenttranslate>
32
+ <table>transfluenttranslate</table>
33
+ </transfluenttranslate>
34
+ </entities>
35
+ </transfluenttranslate_mysql4>
36
+ </models>
37
+
38
+ <helpers>
39
+ <transfluenttranslate>
40
+ <class>Transfluent_Translate_Helper</class>
41
+ </transfluenttranslate>
42
+ </helpers>
43
+
44
+ <blocks>
45
+ <transfluenttranslate>
46
+ <class>Transfluent_Translate_Block</class>
47
+ </transfluenttranslate>
48
+ <adminhtml>
49
+ <rewrite>
50
+ <catalog_product_grid>Transfluent_Translate_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
51
+ <tag_tag_grid>Transfluent_Translate_Block_Adminhtml_Tag_Tag_Grid</tag_tag_grid>
52
+ </rewrite>
53
+ </adminhtml>
54
+ </blocks>
55
+
56
+ <resources>
57
+ <transfluenttranslate_setup>
58
+ <setup>
59
+ <module>Transfluent_Translate</module>
60
+ </setup>
61
+ <connection>
62
+ <use>core_setup</use>
63
+ </connection>
64
+ </transfluenttranslate_setup>
65
+
66
+ <transfluenttranslate_write>
67
+ <connection>
68
+ <use>core_write</use>
69
+ </connection>
70
+ </transfluenttranslate_write>
71
+ <transfluenttranslate_read>
72
+ <connection>
73
+ <use>core_read</use>
74
+ </connection>
75
+ </transfluenttranslate_read>
76
+ </resources>
77
+
78
+ <events>
79
+ <catalog_product_save_after>
80
+ <observers>
81
+ <transfluent_product_hook>
82
+ <type>singelton</type>
83
+ <class>transfluenttranslate/observer</class>
84
+ <method>hookDispatchSaveProduct</method>
85
+ </transfluent_product_hook>
86
+ </observers>
87
+ </catalog_product_save_after>
88
+ <adminhtml_block_html_before>
89
+ <observers>
90
+ <transfluent_product_translate_hook>
91
+ <type>singelton</type>
92
+ <class>transfluenttranslate/observer</class>
93
+ <method>hookDispatchAdminhtmlBlockHtmlBefore</method>
94
+ </transfluent_product_translate_hook>
95
+ </observers>
96
+ </adminhtml_block_html_before>
97
+ </events>
98
+ </global>
99
+
100
+ <admin>
101
+ <routers>
102
+ <transfluenttranslate>
103
+ <use>admin</use>
104
+ <args>
105
+ <module>Transfluent_Translate</module>
106
+ <frontName>transfluent</frontName>
107
+ </args>
108
+ </transfluenttranslate>
109
+ </routers>
110
+ </admin>
111
+
112
+ <adminhtml>
113
+ <layout>
114
+ <updates>
115
+ <transfluenttranslate>
116
+ <file>transfluent.xml</file>
117
+ </transfluenttranslate>
118
+ </updates>
119
+ </layout>
120
+
121
+ <acl>
122
+ <resources>
123
+ <admin>
124
+ <children>
125
+ <system>
126
+ <children>
127
+ <config>
128
+ <children>
129
+ <transfluenttranslate>
130
+ <title>Transfluent translate</title>
131
+ </transfluenttranslate>
132
+ </children>
133
+ </config>
134
+ </children>
135
+ </system>
136
+ </children>
137
+ </admin>
138
+ </resources>
139
+ </acl>
140
+
141
+ <menu>
142
+ <transfluenttranslate module="transfluenttranslate">
143
+ <title>Translations</title>
144
+ <children>
145
+ <submenu translate="title" module="transfluenttranslate">
146
+ <title>Order translations by categories</title>
147
+ <action>transfluenttranslate/adminhtml_transfluentorder/getquote</action>
148
+ </submenu>
149
+ </children>
150
+ <sort_order>71</sort_order>
151
+ <action>transfluenttranslate/adminhtml_transfluenttranslate</action>
152
+ </transfluenttranslate>
153
+ </menu>
154
+ </adminhtml>
155
+ </config>
app/code/community/Transfluent/Translate/etc/system.xml ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <transfluenttranslate translate="label">
5
+ <label>Transfluent</label>
6
+ <sort_order>250</sort_order>
7
+ </transfluenttranslate>
8
+ </tabs>
9
+ <sections>
10
+ <transfluenttranslate translate="label" module="transfluenttranslate">
11
+ <label>Transfluent Settings</label>
12
+ <tab>transfluenttranslate</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>1</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <transfluenttranslate_create translate="label">
20
+ <expanded>true</expanded>
21
+ <label>Create account</label>
22
+ <frontend_class>create_account_tab</frontend_class>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <fields>
29
+ <client_reg translate="label">
30
+ <label>Account information</label>
31
+ <frontend_model>transfluenttranslate/regform</frontend_model>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>4</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>1</show_in_website>
36
+ <show_in_store>1</show_in_store>
37
+ </client_reg>
38
+ </fields>
39
+ </transfluenttranslate_create>
40
+ <transfluenttranslate_login translate="label">
41
+ <expanded>true</expanded>
42
+ <label>Authenticate</label>
43
+ <frontend_class>login_account_auth</frontend_class>
44
+ <frontend_type>text</frontend_type>
45
+ <sort_order>2</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>1</show_in_website>
48
+ <show_in_store>1</show_in_store>
49
+ <fields>
50
+ <client_login translate="label">
51
+ <label>Account information</label>
52
+ <frontend_model>transfluenttranslate/loginform</frontend_model>
53
+ <frontend_type>text</frontend_type>
54
+ <sort_order>5</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>1</show_in_website>
57
+ <show_in_store>1</show_in_store>
58
+ </client_login>
59
+ </fields>
60
+ </transfluenttranslate_login>
61
+ <transfluenttranslate_settings translate="label">
62
+ <label>Default settings</label>
63
+ <frontend_class>transfluen_default_settings</frontend_class>
64
+ <frontend_type>text</frontend_type>
65
+ <sort_order>3</sort_order>
66
+ <show_in_default>1</show_in_default>
67
+ <show_in_website>1</show_in_website>
68
+ <show_in_store>1</show_in_store>
69
+ <fields>
70
+ <transfluent_default_language translate="label">
71
+ <label>Default source language</label>
72
+ <source_model>transfluenttranslate/config_source_language</source_model>
73
+ <frontend_type>select</frontend_type>
74
+ <sort_order>3</sort_order>
75
+ <show_in_default>1</show_in_default>
76
+ <show_in_website>0</show_in_website>
77
+ <show_in_store>0</show_in_store>
78
+ <comment>Translate from language</comment>
79
+ </transfluent_default_language>
80
+ <transfluent_default_quality translate="label">
81
+ <label>Default translator level</label>
82
+ <source_model>transfluenttranslate/config_source_quality</source_model>
83
+ <frontend_type>select</frontend_type>
84
+ <sort_order>2</sort_order>
85
+ <show_in_default>1</show_in_default>
86
+ <show_in_website>0</show_in_website>
87
+ <show_in_store>0</show_in_store>
88
+ </transfluent_default_quality>
89
+ <transfluent_instructions translate="label">
90
+ <label>Default instructions</label>
91
+ <frontend_type>textarea</frontend_type>
92
+ <sort_order>1</sort_order>
93
+ <show_in_default>1</show_in_default>
94
+ <show_in_website>1</show_in_website>
95
+ <show_in_store>1</show_in_store>
96
+ <comment><![CDATA[Instructions will be sent to translator accompanied with product page link. <span class="notice">Remember to click on <strong>Save Config</strong> after changes!</span>]]></comment>
97
+ </transfluent_instructions>
98
+ </fields>
99
+ </transfluenttranslate_settings>
100
+ <transfluenttranslate_help translate="label">
101
+ <expanded>true</expanded>
102
+ <label>Help &amp; Support</label>
103
+ <frontend_class>transfluent_help_support</frontend_class>
104
+ <frontend_type>text</frontend_type>
105
+ <sort_order>4</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ <comment><![CDATA[<img src="http://cdn.transfluent.com/transfluent.com/gfx/transfluent-logo_v3.png"><br>
110
+ <strong>Support:</strong> <a href="support@transfluent.com">support@transfluent.com</a><br>
111
+ <strong>Extension version:</strong> 1.1.5<br>
112
+ <strong>Extension homepage:</strong> <a href="http://www.transfluent.com/products/magento/">transfluent.com/products/magento</a>
113
+ ]]></comment>
114
+ <fields>
115
+ <run translate="label">
116
+ <label>Help</label>
117
+ <frontend_type>text</frontend_type>
118
+ <frontend_model>transfluenttranslate/help</frontend_model>
119
+ <sort_order>1</sort_order>
120
+ <show_in_default>1</show_in_default>
121
+ <show_in_website>1</show_in_website>
122
+ <show_in_store>1</show_in_store>
123
+ </run>
124
+ </fields>
125
+ </transfluenttranslate_help>
126
+ <![CDATA[
127
+ <transfluenttranslate_translate_all_products translate="label">
128
+ <label>Estimate costs and translate all products</label>
129
+ <frontend_class>translate_products</frontend_class>
130
+ <frontend_type>text</frontend_type>
131
+ <sort_order>4</sort_order>
132
+ <show_in_default>1</show_in_default>
133
+ <show_in_website>1</show_in_website>
134
+ <show_in_store>1</show_in_store>
135
+ <fields>
136
+ <client_login translate="label">
137
+ <label>Estimate translation costs for all products</label>
138
+ <frontend_model>transfluenttranslate/translblock</frontend_model>
139
+ <frontend_type>text</frontend_type>
140
+ <sort_order>5</sort_order>
141
+ <show_in_default>1</show_in_default>
142
+ <show_in_website>1</show_in_website>
143
+ <show_in_store>1</show_in_store>
144
+ </client_login>
145
+ </fields>
146
+ </transfluenttranslate_translate_all_products>
147
+ ]]>
148
+ </groups>
149
+ </transfluenttranslate>
150
+ </sections>
151
+ </config>
app/code/community/Transfluent/Translate/sql/transfluenttranslate_setup/mysql4-install-1.1.0.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Transfluent extension for Magento, (c) 2013, 1.1.1
4
+ * Author: coders@transfluent.com
5
+ */
6
+ $installer = $this;
7
+ /* @var $installer Mage_Core_Model_Resource_Setup */
8
+ $installer->startSetup();
9
+ $installer->run("
10
+ DROP TABLE IF EXISTS {$this->getTable('transfluenttranslate')};
11
+ CREATE TABLE {$this->getTable('transfluenttranslate')} (
12
+ `id` int unsigned NOT NULL auto_increment,
13
+ `source_text_hash` varchar(32) NULL,
14
+ `text_id` varchar(255) NOT NULL,
15
+ -- `type` int unsigned NOT NULL,
16
+ -- `ref_id` int unsigned NOT NULL,
17
+ -- `order_id` int unsigned NOT NULL,
18
+ -- `word_count` int unsigned NOT NULL,
19
+ `source_store` int unsigned NOT NULL,
20
+ `target_store` int unsigned NOT NULL,
21
+ `source_language` int unsigned NOT NULL,
22
+ `target_language` int unsigned NOT NULL,
23
+ `level` int unsigned NOT NULL,
24
+ `status` int unsigned NOT NULL,
25
+ `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
26
+ PRIMARY KEY (`id`)
27
+ -- KEY `order_idx` (`order_id`),
28
+ -- KEY `ref_idx` (`type`, `ref_id`)
29
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
30
+ ");
31
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/transfluent.xml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <layout version="1.1.1">
4
+ <default>
5
+ <reference name="head">
6
+ <action method="addJs"><script>transfluent/lib.js</script></action>
7
+ </reference>
8
+ </default>
9
+ <adminhtml_system_config_edit>
10
+ <reference name="head">
11
+ <action method="addJs"><script>transfluent/actions.js</script></action>
12
+ </reference>
13
+ </adminhtml_system_config_edit>
14
+ <transfluenttranslate_transfluenttranslate_estimate>
15
+ <block type="transfluenttranslate/estimate" name="root" output="toHtml" template="transfluent/estimate.phtml"/>
16
+ </transfluenttranslate_transfluenttranslate_estimate>
17
+ </layout>
app/design/adminhtml/default/default/template/transfluent/account/action.phtml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ //<![CDATA[
3
+ var transfluentAccount = new TransfluentAccount({
4
+ cUrl: '<?php echo $this->getUrl('transfluent/adminhtml_account/create', array('key' => $this->getKey('create'))) ?>',
5
+ aUrl: '<?php echo $this->getUrl('transfluent/adminhtml_account/authenticate', array('key' => $this->getKey('authenticate'))) ?>',
6
+ lUrl: '<?php echo $this->getUrl('transfluent/adminhtml_account/logout', array('key' => $this->getKey('logout'))) ?>'
7
+ });
8
+
9
+ function transfluentCreate() {
10
+ transfluentAccount.setCreateData();
11
+ transfluentAccount.accountCreate();
12
+ }
13
+
14
+ function transfluentAuthenticate() {
15
+ transfluentAccount.setAuthData();
16
+ transfluentAccount.accountAuthenticate();
17
+ }
18
+
19
+ function transfluentLogout() {
20
+ transfluentAccount.accountLogout();
21
+ }
22
+ //]]>
23
+ </script>
app/design/adminhtml/default/default/template/transfluent/account/create.phtml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table cellspacing="0" class="form-list">
2
+ <colgroup class="label"></colgroup>
3
+ <colgroup class="value"></colgroup>
4
+ <tbody>
5
+ <tr>
6
+ <td class="label"><label
7
+ for="transfluent_create_email"><?php echo $this->__('Email') ?></label>
8
+ </td>
9
+ <td class="value">
10
+ <input id="transfluent_create_email" name="transfluent_create_email"
11
+ value="" class="input-text" type="text"/>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td class="label"><label
16
+ for="transfluent_create_terms"><?php echo $this->__('Terms of Service') ?></label>
17
+ </td>
18
+ <td class="value">
19
+ <input id="transfluent_create_terms" name="transfluent_create_terms"
20
+ value="" class="" type="checkbox"/>
21
+
22
+ <p class="note"><span><?php echo $this->__('Accept the') ?> <a
23
+ target="_blank"
24
+ href="http://transfluent.com/terms/"><?php echo $this->__('Terms of Service') ?></a>?</span>
25
+ </p>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td class="label"><label> </label></td>
30
+ <td class="value">
31
+ <button id="transfluent_create_button"
32
+ title="<?= $this->__('Register') ?>" type="button"
33
+ class="scalable" onclick="transfluentCreate()" style="">
34
+ <span><span><span><?php echo $this->__('Create account') ?></span></span></span>
35
+ </button>
36
+ </td>
37
+ </tr>
38
+ </tbody>
39
+ </table>
app/design/adminhtml/default/default/template/transfluent/account/logged.phtml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table cellspacing="0" class="form-list">
2
+ <colgroup class="label"></colgroup>
3
+ <colgroup class="value"></colgroup>
4
+ <tbody>
5
+ <tr>
6
+ <td class="label">
7
+ <label><?php echo $this->__('Authenticated account') ?></label></td>
8
+ <td class="value"><?php echo $this->getEmail() ?></td>
9
+ </tr>
10
+ <tr>
11
+ <td class="label"><label> </label></td>
12
+ <td class="value">
13
+ <button id="transfluent_logout_button"
14
+ title="<?php echo $this->__('Invalidate authentication') ?>"
15
+ type="button" class="scalable" onclick="transfluentLogout()"
16
+ style="">
17
+ <span><span><span><?php echo $this->__('Invalidate authentication') ?></span></span></span>
18
+ </button>
19
+ </td>
20
+ </tr>
21
+ </tbody>
22
+ </table>
app/design/adminhtml/default/default/template/transfluent/account/login.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table cellspacing="0" class="form-list">
2
+ <colgroup class="label"></colgroup>
3
+ <colgroup class="value"></colgroup>
4
+ <tbody>
5
+ <tr>
6
+ <td class="label"><label
7
+ for="transfluent_login_email"><?php echo $this->__('Email') ?></label>
8
+ </td>
9
+ <td class="value">
10
+ <input id="transfluent_login_email" name="transfluent_login_email"
11
+ value="" class="input-text" type="text"/>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td class="label"><label
16
+ for="transfluent_login_password"><?php echo $this->__('Password') ?></label>
17
+ </td>
18
+ <td class="value">
19
+ <input id="transfluent_login_password"
20
+ name="transfluent_login_password" value="" class="input-text"
21
+ type="password"/>
22
+ </td>
23
+ </tr>
24
+ <tr>
25
+ <td class="label"><label> </label></td>
26
+ <td class="value">
27
+ <button id="transfluent_login_button"
28
+ title="<?php echo $this->__('Authenticate') ?>"
29
+ type="button" class="scalable"
30
+ onclick="transfluentAuthenticate()" style="">
31
+ <span><span><span><?php echo $this->__('Login') ?></span></span></span>
32
+ </button>
33
+ </td>
34
+ </tr>
35
+ </tbody>
36
+ </table>
app/design/adminhtml/default/default/template/transfluent/estimate.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $est = $this->getEstimate();
3
+ $count = $est['count'];
4
+ $price = $est['price'];
5
+ $currency = $est['currency'];
6
+ $est_all = $est['est_all'];
7
+ $est_suc = $est['est_suc'];
8
+ ?>
9
+ <?php if ($est_suc == 0) : ?>
10
+ <p style="color: #c00;"><?php echo $this->__('Estimation failed. Please try again!') ?></p>
11
+ <?php else : ?>
12
+ <?php if ($est_suc < $est_all) : ?>
13
+ <p style="color: #F57900;"><?php echo $this->__('Some texts was not estimated!') ?></p>
14
+ <?php else : ?>
15
+ <p style="color: #4E9A06;"><?php echo $this->__('Estimation was successful!') ?></p>
16
+ <p><?php echo $this->__('Total word count') ?>: <?php echo $count ?></p>
17
+ <p><?php echo $this->__('Amount') ?>
18
+ : <?php echo $price . " " . $currency ?></p>
19
+ <p>
20
+ <small><?php echo $this->__('* if you do not want to translate estimated text, please click "Cancel" button!') ?></small>
21
+ </p>
22
+ <?php endif; ?>
23
+ <div>
24
+ <button id="translate_estimate"
25
+ title="<?php echo $this->__('Translate estimated text') ?>"
26
+ type="button" class="scalable" onclick="translateEstimated()">
27
+ <span><span><span><?php echo $this->__('Translate estimated text') ?></span></span></span>
28
+ </button>
29
+ <button id="cancel_estimate" title="<?php echo $this->__('Cancel') ?>"
30
+ type="button" class="scalable" onclick="cancelEstimated()">
31
+ <span><span><span><?php echo $this->__('Cancel') ?></span></span></span>
32
+ </button>
33
+ </div>
34
+ <?php endif; ?>
35
+
36
+ <?php $this->clearEstimate(); ?>
app/design/adminhtml/default/default/template/transfluent/estimate_section.phtml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+ <div
4
+ class="notification-global"><?php echo $this->__('Cost estimation will be available in next release.') ?></div><?php
5
+ return;
6
+ /** @var Transfluent_Translate_Block_Estimate $this */
7
+ if (!$this->getRequest()->getParam('store')) {
8
+ ?>
9
+ <div
10
+ class="notification-global"><?php echo $this->__('Please select active store view first.') ?></div><?php
11
+ return;
12
+ }
13
+ $stores = Mage::app()->getStores();
14
+ if (!$stores || count($stores) < 2) {
15
+ ?>
16
+ <div
17
+ class="notification-global"><?php echo $this->__('Please configure at least two store views.') ?></div><?php
18
+ return;
19
+ }
20
+ $helper = Mage::helper('transfluenttranslate/languages');
21
+ /** @var Transfluent_Translate_Helper_Languages $helper */
22
+ $possible_source_languages = array();
23
+ foreach ($stores AS $store) {
24
+ /** @var Mage_Core_Model_Store $store */
25
+ if ($this->getRequest()->getParam('store') == $store->getCode()) {
26
+ continue;
27
+ }
28
+ // @todo FIXME: Use store_ids instead!
29
+ $possible_source_languages[] = $helper->GetStoreLocale($store->getCode());
30
+ }
31
+ if (empty($possible_source_languages)) {
32
+ ?>
33
+ <div
34
+ class="notification-global"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div><?php
35
+ return;
36
+ }
37
+ ?>
38
+ <p><?php echo $this->__('Estimate translation costs of all products') ?></p>
39
+ <table cellspacing="0" class="form-list">
40
+ <colgroup class="label"></colgroup>
41
+ <colgroup class="value"></colgroup>
42
+ <colgroup class="value"></colgroup>
43
+ <tbody>
44
+ <tr>
45
+ <td class="label"><?php echo $this->__('Translate into:') ?></td>
46
+ <td class="value"><?php echo $helper->getLanguageNameByCode($helper->GetStoreLocale($this->getRequest()->getParam('store')), true) ?></td>
47
+ <td class="scope-label">[STORE VIEW]</td>
48
+ </tr>
49
+ <tr>
50
+ <td class="label"><label
51
+ for="est_langs"><?php echo $this->__('Translate from:') ?></label>
52
+ </td>
53
+ <td class="value"><?php echo $helper->getSourceLanguageSelectHtml($possible_source_languages) ?></td>
54
+ </tr>
55
+ <tr>
56
+ <td class="label"><label
57
+ for="est_quality"><?php echo $this->__('Translator:') ?></label>
58
+ </td>
59
+ <td class="value"
60
+ id="est_qual"><?php echo Mage::helper('transfluenttranslate/languages')->getQualityHtml($this->getRequest()->getParam('store')) ?></td>
61
+ </tr>
62
+ <tr>
63
+ <td class="label"></td>
64
+ <td class="value" id="estimation_result">
65
+ <button id="est_button" title="<?php echo $this->__('Estimate') ?>"
66
+ type="button" class="scalable" onclick="estimateAll()">
67
+ <span><span><span><?php echo $this->__('Estimate') ?></span></span></span>
68
+ </button>
69
+ </td>
70
+ <script type="text/javascript">
71
+ //<![CDATA[
72
+ var estimate = new Estimate("<?php echo Mage::app()->getRequest()->getParam('store', 0) ?>", {
73
+ prepdata: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/preparedata') ?>',
74
+ savedata: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/savedata') ?>',
75
+ pushtext: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/pushtext') ?>',
76
+ esttexts: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/estimatetexts') ?>'
77
+ });
78
+
79
+ function estimateAll() {
80
+ estimate.prepareData();
81
+ }
82
+
83
+ var postEstimate = new PostEstimate({
84
+ transl: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/translateestimated') ?>',
85
+ cancel: '<?php echo $this->getUrl('transfluent/adminhtml_transfluenttranslate/deleteestimated') ?>'
86
+ });
87
+
88
+ function translateEstimated() {
89
+ postEstimate.translateEstimated();
90
+ }
91
+
92
+ function cancelEstimated() {
93
+ postEstimate.cancelEstimated();
94
+ }
95
+ //]]>
96
+ </script>
97
+ </tr>
98
+ </tbody>
99
+ </table>
app/design/adminhtml/default/default/template/transfluent/order/order.phtml ADDED
@@ -0,0 +1,431 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
9
+ <div class="content-header">
10
+ <h3 class="icon-head head-products"><?= $languageHelper->__('Order translations for whole categories') ?></h3>
11
+ </div>
12
+
13
+ <?php
14
+ $stores = Mage::app()->getStores();
15
+ if (!$stores || count($stores) < 2) {
16
+ ?>
17
+ <div class="notification-global"
18
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div>
19
+
20
+ <?php
21
+ return;
22
+ }
23
+ $possible_source_languages = array();
24
+ foreach ($stores AS $store) {
25
+ /** @var Mage_Core_Model_Store $store */
26
+ if ($this->getRequest()->getParam('store') == $store->getId()) {
27
+ continue;
28
+ }
29
+ $possible_source_languages[] = $store->getId();
30
+ }
31
+ if (empty($possible_source_languages)) {
32
+ ?>
33
+ <div class="notification-global"
34
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div>
35
+ <?php
36
+ return;
37
+ }
38
+ $store_id = $this->getRequest()->getParam('store');
39
+ $current_store = Mage::app()->getStore($store_id);
40
+ ?>
41
+
42
+ <div style="margin-bottom: 10px;">
43
+ <p>
44
+ <?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.'); ?>
45
+ </p>
46
+ <?php printf(
47
+ $this->__('Translate product categories from %s into %s using %s'),
48
+ $languageHelper->getSourceLanguageSelectForOrderHtml($possible_source_languages, 'source_language'),
49
+ $languageHelper->getSourceLanguageSelectForOrderHtml($possible_source_languages, 'destination_language'),
50
+ $languageHelper->getQualityHtml($store_id)
51
+ ); ?>
52
+ <button id="tf_translate_quote" title="Quote" type="button"
53
+ class="scalable btn-translate"
54
+ onclick="QuoteTranslation(this); ResetEstimation(); return false;">
55
+ <span>
56
+ <?php echo $this->__('Get quote'); ?>
57
+ </span>
58
+ </button>
59
+ <br>
60
+
61
+
62
+ <div id="tf_translate_order_result" style="display: none"
63
+ style="padding: 10px;">
64
+ <ul class="messages">
65
+ <li class="success-msg" style="display: none"
66
+ id="tf_translate_order_result_success_msg">
67
+ <ul>
68
+ <li>
69
+ <span
70
+ id="tf_translate_order_result_success_msg_caption">
71
+ <?php echo $this->__('Thank you for the order!'); ?>
72
+ </span>
73
+ </li>
74
+ </ul>
75
+ </li>
76
+ <div class="notification-global" style="display: none"
77
+ id="tf_translate_order_result_error_msg">
78
+ <div id="tf_translate_order_result_error_msg_caption">
79
+ </div>
80
+ </div>
81
+ </ul>
82
+ </div>
83
+
84
+ <div id="tf_translate_get_quote_error" style="display: none"
85
+ style="padding: 10px;">
86
+ <div class="notification-global">
87
+ <div id="tf_translate_get_quote_error_msg">
88
+ </div>
89
+ </div>
90
+ <br>
91
+ <button title="OK" type="button" class="scalable back"
92
+ onclick="ResetEstimation();" style="">
93
+ <span>
94
+ <span>
95
+ <span><?php echo $this->__('OK'); ?></span>
96
+ </span>
97
+ </span>
98
+ </button>
99
+ </div>
100
+
101
+ <div id="tf_translate_form" style="padding: 10px; display: none">
102
+ <div id="tf_translate_form_cost_msg" style="display: none">
103
+ <?php echo $this->__(<<< 'MSG'
104
+ Product details contain <span
105
+ id="tf_translate_quote_words_count"></span> words to translate.
106
+ Translation
107
+ costs <span id="tf_translate_quote_cost"></span><span
108
+ id="tf_translate_quote_currency"></span>.
109
+ MSG
110
+ ); ?>
111
+ </div>
112
+ <div id="tf_translate_form_no_content" style="display: none">
113
+ <?php echo $this->__('Product details contain nothing to translate. Please choose different product fields to translate and update the quote.'); ?>
114
+ </div>
115
+ <br>
116
+
117
+ <div id="tf_translate_form_instruction_box" style="display: none">
118
+ <a href="#"
119
+ onclick="$('tf_translate_form_instructions').toggle(); return false;">
120
+ <?php echo $this->__('Instructions'); ?>
121
+ </a>
122
+ <br>
123
+
124
+ <div id="tf_translate_form_instructions" style="display: none;">
125
+ <textarea id="tf_translate_instructions_txt" name="instructions"
126
+ cols=60 rows=4>
127
+ </textarea>
128
+ <br>
129
+ </div>
130
+ </div>
131
+
132
+ <div id="tf_translate_form_product_attributes" style="display: none">
133
+ - <a href="#"
134
+ onclick="$('tf_translate_form_fields').toggle(); return false;">
135
+ <?php echo $this->__('Product details to translate'); ?>
136
+ </a>
137
+ <br>
138
+
139
+ <div id="tf_translate_form_fields" style="display: none;">
140
+ <select multiple
141
+ onchange="$('quote_action_buttons_container').hide(); $('get_new_quote_button').show();"
142
+ id="fields_to_translate">
143
+ </select>
144
+
145
+ <div class="form-list">
146
+ <p class="note">
147
+ <span>
148
+ <?php echo $this->__('Hold down CTRL- (PC) or Command-key (MAC) to select multiple items.'); ?>
149
+ </span>
150
+ </p>
151
+ </div>
152
+ </div>
153
+
154
+ <br>
155
+
156
+ <div id="tf_translate_form_force_translate"
157
+ class="form-list" style="display: none">
158
+ <p>
159
+ <input type="checkbox" id="force_translate"
160
+ name="force_translate" value='0'/>
161
+ <?php echo $this->__('Force translation'); ?>
162
+ </p>
163
+
164
+ <p class="note">
165
+ <span>
166
+ <?php echo $this->__('Use this to translate content if you have local changes in the target store'); ?>
167
+ </span>
168
+ </p>
169
+ </div>
170
+
171
+ </div>
172
+ <br>
173
+ <span id="quote_action_buttons_container">
174
+ <button title="Order" type="button" id="tf_place_order_btn"
175
+ class="scalable save"
176
+ onclick="OrderTranslation(this); return false;">
177
+ <span>
178
+ <span>
179
+ <span>
180
+ <?php echo $this->__('Order translation'); ?>
181
+ </span>
182
+ </span>
183
+ </span>
184
+ </button>
185
+
186
+ <button title="Cancel" type="button" class="scalable cancel"
187
+ onclick="ResetEstimation();" style="">
188
+ <span>
189
+ <span>
190
+ <span>
191
+ <?php echo $this->__('Cancel'); ?>
192
+ </span>
193
+ </span>
194
+ </span>
195
+ </button>
196
+ </span>
197
+ <span id="get_new_quote_button" style="display: none;">
198
+ <button title="Get new quote" type="button" id="tf_refresh_quote_btn"
199
+ class="scalable save"
200
+ onclick="QuoteTranslation(this); return false;">
201
+ <span>
202
+ <span>
203
+ <span>
204
+ <?php echo $this->__('Update quote'); ?>
205
+ </span>
206
+ </span>
207
+ </span>
208
+ </button>
209
+
210
+ </span>
211
+ </div>
212
+ </div>
213
+
214
+ <!-- categories list -->
215
+ <div style="margin-left: 20px;">
216
+ <?PHP print $categoryHelper->getCategoriesHTML(); ?>
217
+ </div>
218
+
219
+ <script type="text/javascript">
220
+
221
+ /**
222
+ * all categories and products inside (used to get quote data)
223
+ */
224
+ var categoryProducts = <?php print $categoryHelper->getCategoryProducts(); ?>;
225
+
226
+ /**
227
+ * On page load sets source and destination languages
228
+ */
229
+ window.onload = function () {
230
+ var source = document.getElementById("source_language");
231
+ var destination = document.getElementById("destination_language");
232
+
233
+ ManageDestinationLanguageItem(source, destination);
234
+
235
+ source.addEventListener("change", function () {
236
+ ManageDestinationLanguageItem(source, destination);
237
+ });
238
+ };
239
+
240
+ /**
241
+ * Manages selection and disabling of destination language based on sourcelanguage
242
+ */
243
+ function ManageDestinationLanguageItem(source, destination) {
244
+ var selected = source.options[source.selectedIndex].value;
245
+ var destOptions = destination.getElementsByTagName("option");
246
+ for (var i = 0; i < destOptions.length; i++) {
247
+
248
+ destOptions[i].disabled = destOptions[i].value == selected;
249
+
250
+ if (destOptions[i].className == "disabled_item") {
251
+ destOptions[i].selected = true;
252
+ destOptions[i].disabled = true;
253
+ }
254
+ }
255
+ }
256
+
257
+ function OrderTranslation(order_btn) {
258
+
259
+ if (($('destination_language').getValue()) == "") {
260
+ alert("No destination language is being selected!");
261
+ return;
262
+ }
263
+
264
+ if (!getSelectedProducts('chk_group[]').length) {
265
+ alert('No product category is selected!');
266
+ return;
267
+ }
268
+
269
+ $(order_btn).disable();
270
+
271
+ var force_translate = document.getElementById('force_translate').value;
272
+
273
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/order') ?>', {
274
+ method: 'post',
275
+ parameters: {
276
+ 'store_from': $('source_language').getValue(),
277
+ 'store_to': $('destination_language').getValue(),
278
+ 'level': $('tf_translate_level').getValue(),
279
+ 'product_id': JSON.stringify(getSelectedProducts('chk_group[]')),
280
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
281
+ 'force_translate': force_translate,
282
+ 'fields_to_translate[]': $('fields_to_translate').getValue()
283
+ },
284
+ onSuccess: function (response) {
285
+ ResetEstimation();
286
+ var text = response.responseText;
287
+ if (response.responseText.isJSON()) {
288
+ var response_obj = response.responseText.evalJSON();
289
+ hideElementById('tf_translate_form');
290
+ showElementById('tf_translate_order_result');
291
+ if ("success" == response_obj.status) {
292
+ showElementById('tf_translate_order_result_success_msg');
293
+ hideElementById('tf_translate_order_result_error_msg');
294
+ } else if ("error" == response_obj.status) {
295
+ showElementById('tf_translate_order_result_error_msg');
296
+ hideElementById('tf_translate_order_result_success_msg');
297
+ $('tf_translate_order_result_error_msg_caption').update(response_obj.message);
298
+ }
299
+ }
300
+
301
+ },
302
+ onError: function (response) {
303
+ alert('Failed to place order. Please try again!');
304
+ console.log(response.responseText);
305
+ }
306
+ });
307
+ }
308
+
309
+ /**
310
+ * reset estimation
311
+ */
312
+ function ResetEstimation() {
313
+ $('source_language').enable();
314
+ $('tf_translate_level').enable();
315
+ $('tf_translate_quote').enable().show();
316
+ hideElementById('tf_translate_form');
317
+ hideElementById('tf_translate_order_result');
318
+ hideElementById('tf_translate_order_result_error_msg');
319
+ hideElementById('tf_translate_order_result_success_msg');
320
+ }
321
+
322
+ /**
323
+ * get quote for translation
324
+ */
325
+ function QuoteTranslation(quote_btn) {
326
+
327
+ if (($('destination_language').getValue()) == "") {
328
+ alert("No destination language is being selected!");
329
+ return;
330
+ }
331
+
332
+ if (!getSelectedProducts('chk_group[]').length) {
333
+ alert('No product category is selected!');
334
+ return;
335
+ }
336
+
337
+ var fields_to_translate = [];
338
+ if ($('fields_to_translate')) {
339
+ fields_to_translate = $('fields_to_translate').getValue();
340
+ }
341
+ var force_translate = 0;
342
+ if ($('force_translate') && $('force_translate').getValue != "") {
343
+ force_translate = $('force_translate').getValue();
344
+ }
345
+
346
+ var params = {
347
+ 'store_from': $('source_language').getValue(),
348
+ 'store_to': '<?=$this->getRequest()->getParam('store')?>',
349
+ 'level': $('tf_translate_level').getValue(),
350
+ 'force_translate': force_translate,
351
+ 'product_id': JSON.stringify(getSelectedProducts('chk_group[]'))
352
+ };
353
+
354
+ if (null != fields_to_translate) {
355
+ params['fields_to_translate[]'] = fields_to_translate;
356
+ }
357
+
358
+ if ($('tf_translate_instructions_txt')) {
359
+ params.instructions = $('tf_translate_instructions_txt').getValue();
360
+ }
361
+
362
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_quote') ?>', {
363
+ method: 'post',
364
+ parameters: params,
365
+ onSuccess: function (response) {
366
+ $('source_language').disable();
367
+ $('tf_translate_level').disable();
368
+ $('tf_translate_quote').hide();
369
+ var text = response.responseText;
370
+ if (response.responseText.isJSON()) {
371
+ var responseObj = response.responseText.evalJSON();
372
+ $('quote_action_buttons_container').show();
373
+ $('get_new_quote_button').hide();
374
+ if ("success" == responseObj.status) {
375
+ showElementById('tf_translate_form');
376
+ updateQuoteForm(responseObj);
377
+ } else if ("error" == responseObj.status) {
378
+ document.getElementById("tf_translate_get_quote_error_msg").value = responseObj.message;
379
+ showElementById('tf_translate_get_quote_error');
380
+ }
381
+ }
382
+ },
383
+ onError: function () {
384
+ alert('Failed to estimate costs. Please try again!');
385
+ }
386
+ });
387
+ }
388
+
389
+ /**
390
+ * update quote form by json object got from get_quote back-end
391
+ * @param obj
392
+ */
393
+ function updateQuoteForm(obj) {
394
+
395
+ // update and show price and wordcount
396
+ if (typeof(obj.cost) !== 'undefined' && typeof(obj.currency) !== 'undefined' && typeof(obj.wordCount) !== 'undefined') {
397
+ document.getElementById('tf_translate_quote_words_count').innerHTML = obj.wordCount;
398
+ document.getElementById('tf_translate_quote_currency').innerHTML = obj.currency;
399
+ document.getElementById('tf_translate_quote_cost').innerHTML = obj.cost;
400
+ showElementById('tf_translate_form_cost_msg');
401
+ hideElementById('tf_translate_form_no_content');
402
+ } else {
403
+ hideElementById('tf_translate_form_cost_msg');
404
+ showElementById('tf_translate_form_no_content');
405
+ }
406
+
407
+ // update and show instruction box
408
+ if (typeof(obj.instruction) !== 'undefined') {
409
+ document.getElementById('tf_translate_instructions_txt').innerHTML = obj.instruction;
410
+ showElementById('tf_translate_form_instruction_box');
411
+ }
412
+
413
+ // generate product attributes
414
+ if (typeof(obj.productAttributes) !== 'undefined') {
415
+ document.getElementById('fields_to_translate').innerHTML = buildSelectOptions(obj.productAttributes);
416
+ showElementById('tf_translate_form_product_attributes');
417
+ }
418
+
419
+ // enable force translate
420
+ if (obj.translationFields.length == 0 || obj.fieldsAlreadyTranslated != null || obj.forceTranslate == true) {
421
+ document.getElementById('force_translate').value = 1;
422
+ if (obj.forceTranslate == true) {
423
+ document.getElementById('force_translate').checked = true;
424
+
425
+ }
426
+ showElementById('tf_translate_form_force_translate');
427
+ } else {
428
+ document.getElementById('force_translate').value = 0;
429
+ }
430
+ }
431
+ </script>
app/design/adminhtml/default/default/template/transfluent/product/attributes/edit.phtml ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Mage_Core_Block_Template $this */
3
+ $request = Mage::app()->getRequest();
4
+ $attribute_id = $request->getParam('attribute_id');
5
+ $attribute_model = Mage::getModel('eav/entity_attribute');
6
+ /** @var Mage_Eav_Model_Entity_Attribute $attribute_model */
7
+ $attribute = $attribute_model->load($attribute_id);
8
+ /** @var Mage_Eav_Model_Entity_Attribute $attribute */
9
+ if (!$attribute || !$attribute->getId()) {
10
+ return;
11
+ }
12
+ if (!$attribute->getIsVisibleOnFront() && !$attribute->getData('is_user_defined')) {
13
+ // Invisible system attributes (such as "Custom Design") are not translatable
14
+ return;
15
+ }
16
+ ?>
17
+ <div class="content-header">
18
+ <h3 class="icon-head head-products">Translations</h3>
19
+ </div>
20
+ <?php
21
+ $stores = Mage::app()->getStores();
22
+ if (!$stores || count($stores) < 2) {
23
+ ?>
24
+ <div class="notification-global"
25
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div><?php
26
+ return;
27
+ }
28
+ $helper = Mage::helper('transfluenttranslate/languages');
29
+ /** @var Transfluent_Translate_Helper_Languages $helper */
30
+ $possible_languages = array();
31
+ foreach ($stores AS $store) {
32
+ /** @var Mage_Core_Model_Store $store */
33
+ $possible_languages[] = $helper->GetStoreLocale($store->getCode());
34
+ }
35
+ if (empty($possible_languages)) {
36
+ ?>
37
+ <div class="notification-global"
38
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div><?php
39
+ return;
40
+ }
41
+ $store_id = $this->getRequest()->getParam('store');
42
+ print '<div style="margin-bottom: 20px;" id="translate_attribute_form">';
43
+ print '<strong>Translate</strong><br>';
44
+ print '<label><input type="checkbox" name="translate_name" id="translate_name" value="1" checked="checked"> attribute name (e.g. Color -&gt; Farbe)</label><br>';
45
+ print '<label><input type="checkbox" name="translate_values" id="translate_values" value="1" checked="checked"> attribute options (e.g. Black -&gt; Schwarz etc.)</label><br>';
46
+ print '<strong>into</strong> ';
47
+ foreach ($stores AS $store) {
48
+ /** @var Mage_Core_Model_Store $store */
49
+ $store_language = $helper->GetStoreLocale($store->getCode());
50
+ print '<label><input type="checkbox" name="translate_to[]" value="' . $store->getId() . '"> ' . $helper->getLanguageNameByCode($store_language, true) . ' (' . $store->getName() . ')</label> ';
51
+ }
52
+ print '<br> <strong>from</strong> ' . $helper->getSourceLanguageSelectHtmlForStores($stores) . ' <strong>using</strong> ' . $helper->getQualityHtml($store_id) . ' <button id="tf_translate_quote" title="Quote" type="button" class="scalable btn-translate" onclick="QuoteTranslation(this); return false;"><span><span><span>Get quote</span></span></span></button><br>';
53
+ print '<div id="tf_translate_form" style="padding: 10px;"></div>';
54
+ print '</div>';
55
+ ?>
56
+ <script type="text/javascript">
57
+ function OrderTranslation(order_btn) {
58
+ $(order_btn).disable();
59
+ var stores = [];
60
+ $$('#translate_attribute_form input[type="checkbox"][name="translate_to[]"]').each(function (item) {
61
+ var value = $(item).getValue();
62
+ if (!value) {
63
+ return;
64
+ }
65
+ stores.push(value);
66
+ });
67
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/attribute_order') ?>', {
68
+ method: 'post',
69
+ parameters: {
70
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
71
+ 'from_store': $('translateto').getValue(),
72
+ 'stores[]': stores,
73
+ 'level': $('tf_translate_level').getValue(),
74
+ 'attribute_id': '<?=$request->getParam('attribute_id')?>',
75
+ 'translate_name': $('translate_name').getValue(),
76
+ 'translate_values': $('translate_values').getValue()
77
+ },
78
+ onSuccess: function (response) {
79
+ ResetEstimation();
80
+ var text = response.responseText;
81
+ if (response.responseText.isJSON()) {
82
+ var response_obj = response.responseText.evalJSON();
83
+ text = response_obj.message;
84
+ }
85
+ $('tf_translate_form').update(text);
86
+ },
87
+ onError: function (response) {
88
+ alert('Failed to place order. Please try again!');
89
+ console.log(response.responseText);
90
+ }
91
+ });
92
+ }
93
+ function ResetEstimation() {
94
+ $('translate_attribute_form').select('input').each(function (item) {
95
+ item.enable();
96
+ });
97
+ $('translateto').enable();
98
+ $('tf_translate_level').enable();
99
+ $('tf_translate_quote').enable().show();
100
+ $('tf_translate_form').update('');
101
+ }
102
+ function QuoteTranslation(quote_btn) {
103
+ $(quote_btn).disable();
104
+ $('translate_attribute_form').select('input').each(function (item) {
105
+ item.disable();
106
+ });
107
+ var stores = [];
108
+ $$('#translate_attribute_form input[type="checkbox"][name="translate_to[]"]').each(function (item) {
109
+ var value = $(item).getValue();
110
+ if (!value) {
111
+ return;
112
+ }
113
+ stores.push(value);
114
+ });
115
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_attribute_quote') ?>', {
116
+ method: 'post',
117
+ parameters: {
118
+ 'from_store': $('translateto').getValue(),
119
+ 'stores[]': stores,
120
+ 'level': $('tf_translate_level').getValue(),
121
+ 'attribute_id': '<?=$request->getParam('attribute_id')?>',
122
+ 'translate_name': $('translate_name').getValue(),
123
+ 'translate_values': $('translate_values').getValue()
124
+ },
125
+ onSuccess: function (response) {
126
+ $('translateto').disable();
127
+ $('tf_translate_level').disable();
128
+ $('tf_translate_quote').hide();
129
+ var text = response.responseText;
130
+ if (response.responseText.isJSON()) {
131
+ var response_obj = response.responseText.evalJSON();
132
+ text = response_obj.message;
133
+ }
134
+ $('tf_translate_form').update(text);
135
+ },
136
+ onError: function () {
137
+ alert('Failed to estimate costs. Please try again!');
138
+ }
139
+ });
140
+ }
141
+ </script>
app/design/adminhtml/default/default/template/transfluent/product/category/edit.phtml ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="content-header">
2
+ <h3 class="icon-head head-products">Translations</h3>
3
+ </div>
4
+ <?php
5
+ /** @var Mage_Core_Block_Template $this */
6
+ $stores = Mage::app()->getStores();
7
+ if (!$stores || count($stores) < 2) {
8
+ ?>
9
+ <div class="notification-global"
10
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div><?php
11
+ return;
12
+ }
13
+ $helper = Mage::helper('transfluenttranslate/languages');
14
+ /** @var Transfluent_Translate_Helper_Languages $helper */
15
+ $possible_languages = array();
16
+ foreach ($stores AS $store) {
17
+ /** @var Mage_Core_Model_Store $store */
18
+ $possible_languages[] = $helper->GetStoreLocale($store->getCode());
19
+ }
20
+ if (empty($possible_languages)) {
21
+ ?>
22
+ <div class="notification-global"
23
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div><?php
24
+ return;
25
+ }
26
+ $request = Mage::app()->getRequest();
27
+ $store_id = $this->getRequest()->getParam('store');
28
+ print '<div style="margin-bottom: 20px;" id="translate_attribute_form">';
29
+ print '<strong>Translate</strong><br>';
30
+ print '<label><input type="checkbox" name="translate_name" id="translate_name" value="1" checked="checked"> category name</label><br>';
31
+ print '<label><input type="checkbox" name="translate_desc" id="translate_desc" value="1" checked="checked"> category description</label><br>';
32
+ print '<label><input type="checkbox" name="translate_meta" id="translate_meta" value="1" checked="checked"> category meta title, keywords and description</label><br>';
33
+ print '<label><input type="checkbox" name="translate_subcat" id="translate_subcat" value="1" checked="checked"> translate same properties for all subcategories</label><br>';
34
+ print '<strong>into</strong> ';
35
+ foreach ($stores AS $store) {
36
+ /** @var Mage_Core_Model_Store $store */
37
+ $store_language = $helper->GetStoreLocale($store->getCode());
38
+ print '<label><input type="checkbox" name="translate_to[]" value="' . $store->getId() . '"> ' . $helper->getLanguageNameByCode($store_language, true) . ' (' . $store->getName() . ')</label> ';
39
+ }
40
+ print '<br> <strong>from</strong> ' . $helper->getSourceLanguageSelectHtmlForStores($stores) . ' <strong>using</strong> ' . $helper->getQualityHtml($store_id) . ' <button id="tf_translate_quote" title="Quote" type="button" class="scalable btn-translate" onclick="QuoteTranslation(this); return false;"><span><span><span>Get quote</span></span></span></button><br>';
41
+ print '<div id="tf_translate_form" style="padding: 10px;"></div>';
42
+ print '</div>';
43
+ ?>
44
+ <script type="text/javascript">
45
+ function OrderTranslation(order_btn) {
46
+ if (!categoryForm) {
47
+ categoryForm = new varienForm('category_edit_form');
48
+ }
49
+ if (!categoryForm.getCategoryId()) {
50
+ alert('Please save the new category first!');
51
+ return;
52
+ }
53
+ $(order_btn).disable();
54
+ var stores = [];
55
+ $$('#translate_attribute_form input[type="checkbox"][name="translate_to[]"]').each(function (item) {
56
+ var value = $(item).getValue();
57
+ if (!value) {
58
+ return;
59
+ }
60
+ stores.push(value);
61
+ });
62
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/category_order') ?>', {
63
+ method: 'post',
64
+ parameters: {
65
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
66
+ 'from_store': $('translateto').getValue(),
67
+ 'stores[]': stores,
68
+ 'level': $('tf_translate_level').getValue(),
69
+ 'category_id': categoryForm.getCategoryId(),
70
+ 'translate_name': $('translate_name').getValue(),
71
+ 'translate_desc': $('translate_desc').getValue(),
72
+ 'translate_meta': $('translate_meta').getValue(),
73
+ 'translate_subcat': $('translate_subcat').getValue()
74
+ },
75
+ onSuccess: function (response) {
76
+ ResetEstimation();
77
+ var text = response.responseText;
78
+ if (response.responseText.isJSON()) {
79
+ var response_obj = response.responseText.evalJSON();
80
+ text = response_obj.message;
81
+ }
82
+ $('tf_translate_form').update(text);
83
+ },
84
+ onError: function (response) {
85
+ alert('Failed to place order. Please try again!');
86
+ console.log(response.responseText);
87
+ }
88
+ });
89
+ }
90
+ function ResetEstimation() {
91
+ $('translate_attribute_form').select('input').each(function (item) {
92
+ item.enable();
93
+ });
94
+ $('translateto').enable();
95
+ $('tf_translate_level').enable();
96
+ $('tf_translate_quote').enable().show();
97
+ $('tf_translate_form').update('');
98
+ }
99
+ function QuoteTranslation(quote_btn) {
100
+ if (!categoryForm) {
101
+ categoryForm = new varienForm('category_edit_form');
102
+ }
103
+ if (!categoryForm.getCategoryId()) {
104
+ alert('Please save the new category first!');
105
+ return;
106
+ }
107
+ $(quote_btn).disable();
108
+ $('translate_attribute_form').select('input').each(function (item) {
109
+ item.disable();
110
+ });
111
+ var stores = [];
112
+ $$('#translate_attribute_form input[type="checkbox"][name="translate_to[]"]').each(function (item) {
113
+ var value = $(item).getValue();
114
+ if (!value) {
115
+ return;
116
+ }
117
+ stores.push(value);
118
+ });
119
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_category_quote') ?>', {
120
+ method: 'post',
121
+ parameters: {
122
+ 'from_store': $('translateto').getValue(),
123
+ 'stores[]': stores,
124
+ 'level': $('tf_translate_level').getValue(),
125
+ 'category_id': categoryForm.getCategoryId(),
126
+ 'translate_name': $('translate_name').getValue(),
127
+ 'translate_desc': $('translate_desc').getValue(),
128
+ 'translate_meta': $('translate_meta').getValue(),
129
+ 'translate_subcat': $('translate_subcat').getValue()
130
+ },
131
+ onSuccess: function (response) {
132
+ $('translateto').disable();
133
+ $('tf_translate_level').disable();
134
+ $('tf_translate_quote').hide();
135
+ var text = response.responseText;
136
+ if (response.responseText.isJSON()) {
137
+ var response_obj = response.responseText.evalJSON();
138
+ text = response_obj.message;
139
+ }
140
+ $('tf_translate_form').update(text);
141
+ },
142
+ onError: function () {
143
+ alert('Failed to estimate costs. Please try again!');
144
+ }
145
+ });
146
+ }
147
+ </script>
app/design/adminhtml/default/default/template/transfluent/product/edit.phtml ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $language_helper = Mage::helper('transfluenttranslate/languages');
3
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
4
+ ?>
5
+ <div class="content-header">
6
+ <h3 class="icon-head head-products"><?= $language_helper->__('Translations') ?></h3>
7
+ </div>
8
+ <?php
9
+ /** @var Mage_Core_Block_Template $this */
10
+ if (!$this->getRequest()->getParam('store')) {
11
+ ?>
12
+ <ul class="messages" style="margin-bottom: 20px;">
13
+ <li class="notice-msg"><?php echo $this->__('You are viewing default/website values. Please select a store view (from left) to see translation options.') ?></li>
14
+ </ul><?php
15
+ return;
16
+ }
17
+ $stores = Mage::app()->getStores();
18
+ if (!$stores || count($stores) < 2) {
19
+ ?>
20
+ <div class="notification-global"
21
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div><?php
22
+ return;
23
+ }
24
+ $possible_source_languages = array();
25
+ foreach ($stores AS $store) {
26
+ /** @var Mage_Core_Model_Store $store */
27
+ if ($this->getRequest()->getParam('store') == $store->getId()) {
28
+ continue;
29
+ }
30
+ $possible_source_languages[] = $store->getId();
31
+ }
32
+ if (empty($possible_source_languages)) {
33
+ ?>
34
+ <div class="notification-global"
35
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div><?php
36
+ return;
37
+ }
38
+ $request = Mage::app()->getRequest();
39
+ $store_id = $this->getRequest()->getParam('store');
40
+ $current_store = Mage::app()->getStore($store_id);
41
+ ?>
42
+
43
+ <div style="margin-bottom: 20px;">
44
+ <?php printf(
45
+ $this->__('Translate product details into %s (%s) from %s using %s'),
46
+ $current_store->getName(),
47
+ $language_helper->getLanguageNameByCode($language_helper->GetStoreLocale($store_id), true),
48
+ $language_helper->getSourceLanguageSelectHtml($possible_source_languages),
49
+ $language_helper->getQualityHtml($store_id)
50
+ ) ?>
51
+ <button id="tf_translate_quote" title="Quote" type="button"
52
+ class="scalable btn-translate"
53
+ onclick="QuoteTranslation(this); return false;">
54
+ <span>
55
+ <?php echo $this->__('Get quote'); ?>
56
+ </span>
57
+ </button>
58
+ <br>
59
+
60
+ <div id="tf_translate_order_result" style="padding: 10px; display: none">
61
+ <ul class="messages">
62
+ <li class="success-msg" style="display: none"
63
+ id="tf_translate_order_result_success_msg">
64
+ <ul>
65
+ <li>
66
+ <span
67
+ id="tf_translate_order_result_success_msg_caption">
68
+ <?php echo $this->__('Thank you for the order!'); ?>
69
+ </span>
70
+ </li>
71
+ </ul>
72
+ </li>
73
+ <div class="notification-global" style="display: none"
74
+ id="tf_translate_order_result_error_msg">
75
+ <div id="tf_translate_order_result_error_msg_caption">
76
+ </div>
77
+ </div>
78
+ </ul>
79
+ </div>
80
+
81
+ <div id="tf_translate_get_quote_error"
82
+ style="padding: 10px; display: none">
83
+ <div class="notification-global">
84
+ <div id="tf_translate_get_quote_error_msg">
85
+ </div>
86
+ </div>
87
+ <br>
88
+ <button title="OK" type="button" class="scalable back"
89
+ onclick="ResetEstimation();" style="">
90
+ <span>
91
+ <span>
92
+ <span>OK</span>
93
+ </span>
94
+ </span>
95
+ </button>
96
+ </div>
97
+
98
+ <div id="tf_translate_form" style="padding: 10px; display: none">
99
+ <div id="tf_translate_form_cost_msg" style="display: none">
100
+ <?php echo $this->__(<<< 'MSG'
101
+ Product details contain <span
102
+ id="tf_translate_quote_words_count"></span> words to translate.
103
+ Translation
104
+ costs <span id="tf_translate_quote_cost"></span><span
105
+ id="tf_translate_quote_currency"></span>.
106
+ MSG
107
+ ); ?>
108
+ </div>
109
+
110
+ <br>
111
+
112
+ <div id="tf_translate_form_instruction_box" style="display: none">
113
+ <a href="#"
114
+ onclick="$('tf_translate_form_instructions').toggle(); return false;">
115
+ <?php echo $this->__('Instructions'); ?>
116
+ </a>
117
+ <br>
118
+
119
+ <div id="tf_translate_form_instructions" style="display: none;">
120
+ <textarea id="tf_translate_instructions_txt" name="instructions"
121
+ cols=60 rows=4>
122
+ </textarea>
123
+ <br>
124
+ </div>
125
+ </div>
126
+
127
+ <div id="tf_translate_form_product_attributes" style="display: none">
128
+ - <a href="#"
129
+ onclick="$('tf_translate_form_fields').toggle(); return false;">
130
+ <?php echo $this->__('Product details to translate'); ?>
131
+ </a>
132
+ <br>
133
+
134
+ <div id="tf_translate_form_fields" style="display: none;">
135
+ <select multiple
136
+ onchange="$('quote_action_buttons_container').hide(); $('get_new_quote_button').show();"
137
+ id="fields_to_translate">
138
+ </select>
139
+
140
+ <div class="form-list">
141
+ <p class="note">
142
+ <span>
143
+ <?php echo $this->__('Hold down CTRL- (PC) or Command-key (MAC) to select multiple items.'); ?>
144
+ </span>
145
+ </p>
146
+ </div>
147
+ </div>
148
+
149
+ <br>
150
+
151
+ <div id="tf_translate_form_force_translate"
152
+ class="form-list" style="display: none">
153
+ <p>
154
+ <input type="checkbox" id="force_translate"
155
+ name="force_translate" value='0'/>
156
+ Force translation
157
+ </p>
158
+
159
+ <p class="note">
160
+ <span>
161
+ <?php echo $this->__('Use this to translate content if you have local changes in the target store'); ?>
162
+ </span>
163
+ </p>
164
+ </div>
165
+
166
+ </div>
167
+ <br>
168
+ <span id="quote_action_buttons_container">
169
+ <button title="Order" type="button" id="tf_place_order_btn"
170
+ class="scalable save"
171
+ onclick="OrderTranslation(this); return false;">
172
+ <span>
173
+ Order translation
174
+ </span>
175
+ </button>
176
+
177
+ <button title="Cancel" type="button" class="scalable cancel"
178
+ onclick="ResetEstimation();" style="">
179
+ <span>
180
+ Cancel
181
+ </span>
182
+ </button>
183
+ </span>
184
+ <span id="get_new_quote_button" style="display: none;">
185
+ <button title="Get new quote" type="button" id="tf_refresh_quote_btn"
186
+ class="scalable save"
187
+ onclick="QuoteTranslation(this); return false;">
188
+ <span>
189
+ Update quote
190
+ </span>
191
+ </button>
192
+
193
+ </span>
194
+ </div>
195
+ <div id="tf_translate_form_no_content" style="display: none">
196
+ Product details contain nothing to translate. Please choose different
197
+ product fields to translate and update
198
+ the quote.
199
+ </div>
200
+ </div>
201
+
202
+
203
+ <script type="text/javascript">
204
+ function OrderTranslation(order_btn) {
205
+ $(order_btn).disable();
206
+
207
+ var force_translate = 0;
208
+ if ($('force_translate')) {
209
+ force_translate = $('force_translate').getValue();
210
+ }
211
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/order') ?>', {
212
+ method: 'post',
213
+ parameters: {
214
+ 'store_from': $('store_language').getValue(),
215
+ 'store_to': '<?=$request->getParam('store')?>',
216
+ 'level': $('tf_translate_level').getValue(),
217
+ 'product_id': '[' + '<?=$request->getParam('id')?>' + ']', // json object should be passed
218
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
219
+ 'force_translate': force_translate,
220
+ 'fields_to_translate[]': $('fields_to_translate').getValue()
221
+ },
222
+ onSuccess: function (response) {
223
+ ResetEstimation();
224
+ var text = response.responseText;
225
+ console.log(response.responseText);
226
+ if (response.responseText.isJSON()) {
227
+ var response_obj = response.responseText.evalJSON();
228
+ hideElementById('tf_translate_form');
229
+ console.log(response_obj);
230
+ showElementById('tf_translate_order_result');
231
+ if ("success" == response_obj.status) {
232
+ showElementById('tf_translate_order_result_success_msg');
233
+ hideElementById('tf_translate_order_result_error_msg');
234
+ } else if ("error" == response_obj.status) {
235
+ showElementById('tf_translate_order_result_error_msg');
236
+ hideElementById('tf_translate_order_result_success_msg');
237
+ $('tf_translate_order_result_error_msg_caption').update(response_obj.message);
238
+ }
239
+ }
240
+ },
241
+ onError: function (response) {
242
+ alert('Failed to place order. Please try again!');
243
+ console.log(response.responseText);
244
+ }
245
+ });
246
+ }
247
+ function ResetEstimation() {
248
+ $('store_language').enable();
249
+ $('tf_translate_level').enable();
250
+ $('tf_translate_quote').enable().show();
251
+ hideElementById('tf_translate_form');
252
+ hideElementById('tf_translate_order_result');
253
+ hideElementById('tf_translate_order_result_error_msg');
254
+ hideElementById('tf_translate_order_result_success_msg');
255
+ }
256
+ /**
257
+ *
258
+ */
259
+ function QuoteTranslation(quote_btn) {
260
+
261
+ var fields_to_translate = [];
262
+ if ($('fields_to_translate')) {
263
+ fields_to_translate = $('fields_to_translate').getValue();
264
+ }
265
+ var force_translate = 0;
266
+ if ($('force_translate') && $('force_translate').getValue != "") {
267
+ force_translate = $('force_translate').getValue();
268
+ }
269
+
270
+ var params = {
271
+ 'store_from': $('store_language').getValue(),
272
+ 'store_to': '<?=$request->getParam('store')?>',
273
+ 'level': $('tf_translate_level').getValue(),
274
+ 'force_translate': force_translate,
275
+ 'product_id': '[' + '<?=$request->getParam('id')?>' + ']'
276
+ };
277
+
278
+ if (null != fields_to_translate) {
279
+ params['fields_to_translate[]'] = fields_to_translate;
280
+ }
281
+
282
+ if ($('tf_translate_instructions_txt')) {
283
+ params.instructions = $('tf_translate_instructions_txt').getValue();
284
+ }
285
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_quote') ?>', {
286
+ method: 'post',
287
+ parameters: params,
288
+ onSuccess: function (response) {
289
+ $('store_language').disable();
290
+ $('tf_translate_level').disable();
291
+ $('tf_translate_quote').hide();
292
+ var text = response.responseText;
293
+ if (response.responseText.isJSON()) {
294
+ $('quote_action_buttons_container').show();
295
+ $('get_new_quote_button').hide();
296
+ var response_obj = response.responseText.evalJSON();
297
+ if ("success" == response_obj.status) {
298
+ showElementById('tf_translate_form');
299
+ updateQuoteForm(response_obj);
300
+ } else if ("error" == response_obj.status) {
301
+ document.getElementById("tf_translate_get_quote_error_msg").value = response_obj.message;
302
+ showElementById('tf_translate_get_quote_error');
303
+ }
304
+ }
305
+ },
306
+ onError: function () {
307
+ alert('Failed to estimate costs. Please try again!');
308
+ }
309
+ });
310
+ }
311
+
312
+
313
+ /**
314
+ * update quote form by json object got from get_quote back-end
315
+ * @param obj
316
+ */
317
+ function updateQuoteForm(obj) {
318
+
319
+ // update and show price and wordcount
320
+ if (typeof(obj.cost) !== 'undefined' && typeof(obj.currency) !== 'undefined' && typeof(obj.wordCount) !== 'undefined') {
321
+ document.getElementById('tf_translate_quote_words_count').innerHTML = obj.wordCount;
322
+ document.getElementById('tf_translate_quote_currency').innerHTML = obj.currency;
323
+ document.getElementById('tf_translate_quote_cost').innerHTML = obj.cost;
324
+ showElementById('tf_translate_form_cost_msg');
325
+ hideElementById('tf_translate_form_no_content');
326
+ } else {
327
+ hideElementById('tf_translate_form_cost_msg');
328
+ showElementById('tf_translate_form_no_content');
329
+ }
330
+
331
+ // update and show instruction box
332
+ if (typeof(obj.instruction) !== 'undefined') {
333
+ document.getElementById('tf_translate_instructions_txt').innerHTML = obj.instruction;
334
+ showElementById('tf_translate_form_instruction_box');
335
+ }
336
+
337
+ // generate product attributes
338
+ if (typeof(obj.productAttributes) !== 'undefined') {
339
+ document.getElementById('fields_to_translate').innerHTML = buildSelectOptions(obj.productAttributes);
340
+ showElementById('tf_translate_form_product_attributes');
341
+ }
342
+
343
+ // enable force translate
344
+ if (obj.translationFields.length == 0 || obj.fieldsAlreadyTranslated != null || obj.forceTranslate == true) {
345
+ document.getElementById('force_translate').value = 1;
346
+ if (obj.forceTranslate == true) {
347
+ document.getElementById('force_translate').checked = true;
348
+
349
+ }
350
+ showElementById('tf_translate_form_force_translate');
351
+ } else {
352
+ document.getElementById('force_translate').value = 0;
353
+ }
354
+ }
355
+
356
+ </script>
app/design/adminhtml/default/default/template/transfluent/product/index.phtml ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $request = Mage::app()->getRequest();
3
+ if (!$request->isPost()) {
4
+ return;
5
+ }
6
+ set_time_limit(0);
7
+ $language_helper = Mage::helper('transfluenttranslate/languages');
8
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
9
+ ?>
10
+ <div id="tf_translate_form" style="margin-bottom: 20px;">
11
+ <div class="content-header">
12
+ <h3 class="icon-head head-products"><?= $language_helper->__('Translations') ?></h3>
13
+ </div>
14
+ <?php
15
+ /** @var Mage_Core_Block_Template $this */
16
+ if (!$this->getRequest()->getParam('store')) {
17
+ ?>
18
+ <ul class="messages" style="margin-bottom: 20px;">
19
+ <li class="notice-msg"><?php echo $this->__('You are viewing default/website values. Please select a store view (from left) to see translation options.') ?></li>
20
+ </ul>
21
+ </div><?php
22
+ return;
23
+ }
24
+ $stores = Mage::app()->getStores();
25
+ if (!$stores || count($stores) < 2) {
26
+ ?>
27
+ <div class="notification-global"
28
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views.') ?></div></div><?php
29
+ return;
30
+ }
31
+ $possible_source_languages = array();
32
+ foreach ($stores AS $store) {
33
+ /** @var Mage_Core_Model_Store $store */
34
+ if ($this->getRequest()->getParam('store') == $store->getId()) {
35
+ continue;
36
+ }
37
+ $possible_source_languages[] = $store->getId();
38
+ }
39
+ if (empty($possible_source_languages)) {
40
+ ?>
41
+ <div class="notification-global"
42
+ style="margin-bottom: 20px;"><?php echo $this->__('Please configure at least two store views with different locales.') ?></div></div><?php
43
+ return;
44
+ }
45
+
46
+ $force_translate = $this->getRequest()->getParam('force_translate');
47
+ $level = $this->getRequest()->getParam('level');
48
+ $store_from_id = $this->getRequest()->getParam('translate_from');
49
+ $store_to_id = $this->getRequest()->getParam('translate_store');
50
+ $source_language = $language_helper->GetStoreLocale($store_from_id);
51
+ $source_language_id = $language_helper->getLangByCode($source_language, true);
52
+
53
+ $products = $this->getRequest()->getParam('product');
54
+ $fields_to_translate_in = $this->getRequest()->getParam('fields_to_translate');
55
+ $translate_fields = array();
56
+ if (empty($fields_to_translate_in)) {
57
+ foreach ($language_helper->DefaultProductFieldsToTranslate() AS $default_field_to_translate) {
58
+ $translate_fields[] = $default_field_to_translate;
59
+ }
60
+ } else {
61
+ $translate_fields = $fields_to_translate_in;
62
+ }
63
+ ?>
64
+
65
+ <script type="text/javascript">
66
+ function OrderTranslation(order_btn) {
67
+ $(order_btn).disable();
68
+ new Ajax.Request('<?=$this->getUrl('transfluenttranslate/adminhtml_transfluentorder/grid_order')?>', {
69
+ method: 'post',
70
+ parameters: {
71
+ 'translate_from': '<?=$store_from_id?>',
72
+ 'store_to': '<?=$store_to_id?>',
73
+ 'level': '<?=$level?>',
74
+ 'force_translate': ($('force_translate') ? $('force_translate').getValue() : 0),
75
+ 'products[]': <?=Mage::helper('core')->jsonEncode($products)?>,
76
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
77
+ 'fields_to_translate[]': $('fields_to_translate').getValue()
78
+ },
79
+ onSuccess: function (response) {
80
+ window.location.href = '<?=$this->getUrl('adminhtml/catalog_product', array('store' => $store_to_id))?>';
81
+ return;
82
+ },
83
+ onError: function (response) {
84
+ window.location.href = '<?=$this->getUrl('adminhtml/catalog_product', array('store' => $store_to_id))?>';
85
+ return;
86
+ }
87
+ });
88
+ }
89
+ function ResetEstimation() {
90
+ $('tf_translate_quote').enable().show();
91
+ $('tf_translate_form').update('');
92
+ }
93
+ </script>
94
+
95
+ <?php
96
+
97
+ $tf_client = Mage::getModel('transfluenttranslate/base_backendclient');
98
+ /** @var Transfluent_Translate_Model_Base_Backendclient $tf_client */
99
+
100
+ $text = '';
101
+ foreach ($products as $product_id) {
102
+ $product = Mage::getModel('catalog/product')->setStoreId($store_from_id)->load($product_id);
103
+ /** @var Mage_Catalog_Model_Product $product */
104
+ if (!$product) {
105
+ continue;
106
+ }
107
+ $translated_product = Mage::getModel('catalog/product')->setStoreId($store_to_id)->load($product->getId());
108
+ /** @var Mage_Catalog_Model_Product $translated_product */
109
+
110
+ foreach ($translate_fields AS $translate_field) {
111
+ if (!$force_translate && $translated_product->getExistsStoreValueFlag($translate_field)) {
112
+ continue;
113
+ }
114
+ $text .= $product->getData($translate_field) . PHP_EOL;
115
+ }
116
+ }
117
+
118
+ $target_language = $language_helper->GetStoreLocale($store_to_id);
119
+ $target_language_id = $language_helper->getLangByCode($target_language, true);
120
+ $response = $tf_client->FreeTextWordCount($level, $text, $source_language_id, $target_language_id);
121
+
122
+ if ($response && @$response['status'] == 'OK') {
123
+ $response = $response['response'];
124
+ if ($response['count'] == 0) {
125
+ print 'Details for products contain nothing to translate. Please choose different products or fields to translate and update the quote.<br>';
126
+ } else {
127
+ print 'Details for products contain ' . $response['count'] . ' words to translate. Translation costs ' . $response['price']['amount'] . $response['price']['currency'] . '.<br>';
128
+ }
129
+ print '<form action="' . Mage::app()->getRequest()->getRequestUri() . '" method="POST">';
130
+ print '<input type="hidden" name="form_key" value="' . htmlspecialchars(Mage::getSingleton('core/session')->getFormKey()) . '">';
131
+ print '<input type="hidden" name="level" value="' . htmlspecialchars($level) . '">';
132
+ print '<input type="hidden" name="translate_from" value="' . htmlspecialchars($store_from_id) . '">';
133
+ print '<input type="hidden" name="translate_store" value="' . htmlspecialchars($store_to_id) . '">';
134
+ print '<input type="hidden" name="product" value="' . implode(",", $products) . '">';
135
+ print '<input type="hidden" name="massaction_prepare_key" value="product">';
136
+ print ' - <a href="#" onclick="$(\'tf_translate_form_instructions\').toggle(); return false;">Instructions</a><br>';
137
+ $instructions = $this->getRequest()->getParam('instructions') ? $this->getRequest()->getParam('instructions') : Mage::getStoreConfig('transfluenttranslate/transfluenttranslate_settings/transfluent_instructions', $store_to_id);
138
+ $instructions = $instructions ? $instructions : '';
139
+ print '<div id="tf_translate_form_instructions" style="display: none;"><textarea id="tf_translate_instructions_txt" name="instructions" cols=60 rows=4>' . Mage::helper('core')->quoteEscape($instructions) . '</textarea><br></div>';
140
+ print ' - <a href="#" onclick="$(\'tf_translate_form_fields\').toggle(); return false;">Product details to translate</a><br>';
141
+ print '<div id="tf_translate_form_fields" style="display: none;">';
142
+ print '<select multiple onchange="$(\'quote_action_buttons_container\').hide(); $(\'get_new_quote_button\').show();" id="fields_to_translate" name="fields_to_translate[]">';
143
+ $non_translatable_attributes = array(
144
+ 'weight', 'status', 'tax_class_id', 'visibility', 'news_from_date', 'news_to_date', 'price', 'group_price', 'cost', 'tier_price', 'special_price',
145
+ 'special_from_date', 'special_to_date', 'enable_googlecheckout', 'msrp_enabled', 'msrp_display_actual_price_type', 'msrp', 'thumbnail', 'small_image',
146
+ 'image', 'gallery', 'media_gallery', 'custom_design_from', 'custom_design_to', 'custom_layout_update', 'options_container', 'page_layout', 'is_recurring',
147
+ 'recurring_profile', 'gift_message_available',
148
+ );
149
+ foreach ($product->getAttributes() AS $attribute) {
150
+ /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
151
+ if (!$attribute->getIsVisible() || $attribute->isStatic() || $attribute->isDeleted() || $attribute->getIsGlobal()) {
152
+ continue;
153
+ }
154
+ if (in_array($attribute->getName(), $non_translatable_attributes)) {
155
+ continue;
156
+ }
157
+ if ($attribute->usesSource()) {
158
+ continue;
159
+ }
160
+ print '<option value="' . $attribute->getName() . '"' . (in_array($attribute->getName(), $translate_fields) ? ' selected="selected"' : '') . '>' . $attribute->getFrontend()->getLabel() . '</option>';
161
+ }
162
+ print '</select>';
163
+ print '<div class="form-list"><p class="note"><span>Hold down CTRL- (PC) or Command-key (MAC) to select multiple items.</span></p></div>';
164
+ print '<br></div>';
165
+ print '<br>';
166
+ if (empty($translate_fields) || $force_translate || $response['count'] == 0 || $text == '') {
167
+ print '<div class="form-list"><p><input type="checkbox" id="force_translate" name="force_translate" value="1"' . ($force_translate ? 'checked="CHECKED" ' : '') . ' /> Force translation</p><p class="note"><span>Use this to translate content if you have local changes in the target store</span></p></div>';
168
+ print '<br>';
169
+ }
170
+ print '<span id="quote_action_buttons_container"' . ($response['count'] == 0 ? ' style="display: none;"' : '') . '>';
171
+ print '<button title="Order" type="button" id="tf_place_order_btn" class="scalable save" onclick="OrderTranslation(this); return false;"><span><span><span>Order translation</span></span></span></button> ';
172
+ print '<button title="Cancel" type="button" class="scalable cancel" onclick="ResetEstimation();" style=""><span><span><span>Cancel</span></span></span></button>';
173
+ print '</span><span id="get_new_quote_button"' . ($response['count'] == 0 ? '' : ' style="display: none;"') . '>';
174
+ print '<button title="Get new quote" type="submit" id="tf_refresh_quote_btn" class="scalable save"><span><span><span>Update quote</span></span></span></button> ';
175
+ print '</span></form></div>';
176
+ return;
177
+ } else if ($response && @$response['status'] == 'ERROR') {
178
+ if ($response && @$response['status'] == 'ERROR' && @$response['error']['type']) {
179
+ $e = Transfluent_Translate_Exception_Base::create($response['error']['type']);
180
+ if ($e !== null)
181
+ $error_msg = $e->getMessage();
182
+ }
183
+ }
184
+ $error_msg = (isset($error_msg) ? $error_msg : 'An error occurred and costs could not be estimated at the moment. Please try again!');
185
+ print '<div class="notification-global">' . $error_msg . '</div><br>';
186
+ print '<button title="OK" type="button" class="scalable back" onclick="ResetEstimation();" style=""><span><span><span>OK</span></span></span></button>';
187
+
188
+
189
+ ?>
190
+ </div>
app/design/adminhtml/default/default/template/transfluent/tag/tag/index.phtml ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Mage_Core_Block_Template $this */
3
+ if (!$this->getRequest()->getPost()) {
4
+ return;
5
+ }
6
+ set_time_limit(0);
7
+
8
+ $stores = Mage::app()->getStores();
9
+ $level = intval($this->getRequest()->getParam('quality'));
10
+ $store_from_id = intval($this->getRequest()->getParam('store_from'));
11
+ $store_to_id = intval($this->getRequest()->getParam('store_to'));
12
+ $tags = $this->getRequest()->getParam('tag');
13
+
14
+ $language_helper = Mage::helper('transfluenttranslate/languages');
15
+ /** @var Transfluent_Translate_Helper_Languages $language_helper */
16
+ ?>
17
+
18
+ <script type="text/javascript">
19
+
20
+ window.onload = function () {
21
+ GetQuote();
22
+ }
23
+
24
+ function GetQuote() {
25
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluenttranslate/get_tag_quote') ?>', {
26
+ method: 'post',
27
+ parameters: {
28
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
29
+ 'store_from_id': '<?= $store_from_id ?>',
30
+ 'store_to_id': '<?= $store_to_id ?>',
31
+ 'level': '<?= $level ?>',
32
+ 'tags[]': <?=json_encode(array_values($tags))?>
33
+ },
34
+ onSuccess: function (response) {
35
+ var text = response.responseText;
36
+ if (response.responseText.isJSON()) {
37
+ var response_obj = response.responseText.evalJSON();
38
+ if ("success" == response_obj.status) {
39
+ updateQuoteForm(response_obj);
40
+ } else if ("error" == response_obj.status) {
41
+ document.getElementById("tf_translate_get_quote_error_msg").value = response_obj.message;
42
+ showElementById('tf_translate_form_msg');
43
+ showElementById('tf_translate_get_quote_error');
44
+ }
45
+ }
46
+ },
47
+ onError: function (response) {
48
+ alert('Failed to place order. Please try again!');
49
+ console.log(response.responseText);
50
+ }
51
+ });
52
+ }
53
+ </script>
54
+
55
+ <div id="tag-translation-form" style="margin-bottom: 20px;">
56
+ <div class="content-header">
57
+ <h3 class="icon-head head-products">Translations</h3>
58
+ </div>
59
+
60
+ <div id='tf_translate_form_msg' style="display: none">
61
+ <div id="tf_translate_get_quote_error"
62
+ style="padding: 10px; display: none">
63
+ <div class="notification-global" style="padding: 10px;">
64
+ <div id="tf_translate_get_quote_error_msg"
65
+ style="padding:20px;">
66
+ </div>
67
+ </div>
68
+ <br><br>
69
+ <button title="OK" type="button" class="scalable back"
70
+ onclick="ResetEstimation();" style="">
71
+ <span>
72
+ <span>
73
+ <span>OK</span>
74
+ </span>
75
+ </span>
76
+ </button>
77
+ </div>
78
+ <div id="tf_translate_order_result_success_msg"
79
+ style="padding: 10px; display: none">
80
+ <div class="success-msg" id="tf_translate_order_result_success_msg"
81
+ style="padding: 10px;">
82
+ <span id="tf_translate_order_result_success_msg_caption"
83
+ style="padding: 20px;">
84
+ Thank you for the order!
85
+ </span>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <div id="tf_translate_form" style="padding: 10px; display: none">
91
+ <div id="tf_translate_form_cost_msg" style="display: none">
92
+ Tags contain
93
+ <span id="tf_translate_quote_words_count"></span>
94
+ words to translate. Translation costs
95
+ <span id="tf_translate_quote_cost"></span> <span
96
+ id="tf_translate_quote_currency"></span>
97
+ <br>
98
+ - <a href="#"
99
+ onclick="$('tf_translate_form_instructions_box').toggle(); return false;">Instructions</a><br>
100
+ </div>
101
+ <div id="tf_translate_form_instructions_box" style="display: none;">
102
+ <textarea id="tf_translate_instructions_txt" name="instructions"
103
+ cols=60 rows=4>
104
+ </textarea>
105
+ <br>
106
+ </div>
107
+
108
+ <br>
109
+ <span id="quote_action_buttons_container">
110
+ <button title="Order" type="button" id="tf_place_order_btn"
111
+ class="scalable save"
112
+ onclick="OrderTranslation(this); return false;">
113
+ <span>
114
+ Order translation
115
+ </span>
116
+ </button>
117
+ <button title="Cancel" type="button" class="scalable cancel"
118
+ onclick="ResetEstimation();" style="">
119
+ <span>
120
+ Cancel
121
+ </span>
122
+ </button>
123
+ </span>
124
+ </div>
125
+
126
+
127
+ <script type="text/javascript">
128
+
129
+ function ResetEstimation() {
130
+ $('tag-translation-form').hide();
131
+ }
132
+
133
+ /**
134
+ * update quote form by json object got from get_quote back-end
135
+ * @param obj
136
+ */
137
+ function updateQuoteForm(obj) {
138
+
139
+ showElementById('tf_translate_form');
140
+
141
+ // update and show price and wordcount
142
+ if (typeof(obj.cost) !== 'undefined' && typeof(obj.currency) !== 'undefined' && typeof(obj.wordCount) !== 'undefined') {
143
+ document.getElementById('tf_translate_quote_words_count').innerHTML = obj.wordCount;
144
+ document.getElementById('tf_translate_quote_currency').innerHTML = obj.currency;
145
+ document.getElementById('tf_translate_quote_cost').innerHTML = obj.cost;
146
+ showElementById('tf_translate_form_cost_msg');
147
+ hideElementById('tf_translate_form_msg');
148
+ } else {
149
+ hideElementById('tf_translate_form_cost_msg');
150
+ }
151
+
152
+ // update and show instruction box
153
+ if (typeof(obj.instruction) !== 'undefined') {
154
+ document.getElementById('tf_translate_instructions_txt').innerHTML = obj.instruction;
155
+ showElementById('tf_translate_form_instructions_box');
156
+ }
157
+ }
158
+
159
+ function OrderTranslation(order_btn) {
160
+ $(order_btn).disable();
161
+ new Ajax.Request('<?php echo $this->getUrl('transfluenttranslate/adminhtml_transfluentorder/tag_order') ?>', {
162
+ method: 'post',
163
+ parameters: {
164
+ 'instructions': $('tf_translate_instructions_txt').getValue(),
165
+ 'from_store': '<?=htmlspecialchars($store_from_id)?>',
166
+ 'to_store': '<?=htmlspecialchars($store_to_id)?>',
167
+ 'level': '<?=htmlspecialchars($level)?>',
168
+ 'tags[]': <?=json_encode(array_values($tags))?>
169
+ },
170
+ onSuccess: function (response) {
171
+ var text = response.responseText;
172
+ if (response.responseText.isJSON()) {
173
+ var response_obj = response.responseText.evalJSON();
174
+ hideElementById('tf_translate_form');
175
+ showElementById('tf_translate_form_msg');
176
+ if ("success" == response_obj.status) {
177
+ showElementById('tf_translate_order_result_success_msg');
178
+ hideElementById('tf_translate_order_result_error_msg');
179
+ } else if ("error" == response_obj.status) {
180
+ showElementById('tf_translate_order_result_error_msg');
181
+ hideElementById('tf_translate_order_result_success_msg');
182
+ $('tf_translate_get_quote_error_msg').update(response_obj.message);
183
+ }
184
+ }
185
+
186
+ },
187
+ onError: function (response) {
188
+ alert('Failed to place order. Please try again!');
189
+ console.log(response.responseText);
190
+ }
191
+ });
192
+ }
193
+ </script>
app/etc/modules/Transfluent_Translate.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Transfluent_Translate>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Transfluent_Translate>
8
+ </modules>
9
+ </config>
js/transfluent/actions.js ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function TF_CreateAccount(url) {
3
+ new Ajax.Request(url, {
4
+ method: "get",
5
+ parameters: {email: $('transfluent_create_email').value, terms: "ok"},
6
+ onSuccess: function(transport) {
7
+ try {
8
+ if (transport.responseText.isJSON()) {
9
+ var response = transport.responseText.evalJSON();
10
+ switch (response.status) {
11
+ case 'ERROR':
12
+ alert('Error! ' + response.error.message);
13
+ break;
14
+ case 'OK':
15
+ location.reload();
16
+ break;
17
+ }
18
+ }
19
+ } catch (e) {
20
+ alert(e);
21
+ alert(transport.responseText);
22
+ }
23
+ }
24
+ });
25
+ }
26
+
27
+ var TransfluentAccount = Class.create();
28
+ TransfluentAccount.prototype = {
29
+ initialize: function(urls) {
30
+ this.cUrl = urls.cUrl;
31
+ this.aUrl = urls.aUrl;
32
+ this.lUrl = urls.lUrl;
33
+
34
+ this.cEmail = '';
35
+ this.lEmail = '';
36
+ this.pass = '';
37
+ this.terms = '';
38
+ },
39
+
40
+ setCreateData: function() {
41
+ this.cEmail = $('transfluent_create_email').value;
42
+ },
43
+
44
+ setAuthData: function() {
45
+ this.lEmail = $('transfluent_login_email').value;
46
+ this.pass = $('transfluent_login_password').value;
47
+ },
48
+
49
+ accountCreate: function() {
50
+ if (this.cEmail == '') {
51
+ alert('Please provide an email address.');
52
+ return;
53
+ }
54
+
55
+ if (!$('transfluent_create_terms').checked) {
56
+ alert('Please accept Terms of Service.');
57
+ return;
58
+ }
59
+
60
+ new Ajax.Request(this.cUrl, {
61
+ method: "get",
62
+ parameters: { email: this.cEmail, terms: 'ok'},
63
+ onSuccess: function(transport) {
64
+ try {
65
+ if (transport.responseText.isJSON()) {
66
+ var response = transport.responseText.evalJSON();
67
+
68
+ switch (response.status) {
69
+ case 'ERROR':
70
+ alert('Error! ' + response.error.message);
71
+ break;
72
+ case 'OK':
73
+ window.location.reload();
74
+ break;
75
+ }
76
+ }
77
+ } catch (e) {
78
+ alert(e);
79
+ alert(transport.responseText);
80
+ }
81
+ }.bind(this)
82
+ });
83
+ },
84
+
85
+ accountAuthenticate: function() {
86
+ new Ajax.Request(this.aUrl, {
87
+ method: "get",
88
+ parameters: { email: this.lEmail, password: this.pass },
89
+ onSuccess: function(transport) {
90
+ try {
91
+ if (transport.responseText.isJSON()) {
92
+ var response = transport.responseText.evalJSON();
93
+ if (response.status == 'ok') {
94
+ window.location.reload();
95
+ } else {
96
+ alert(response.message);
97
+ }
98
+ }
99
+ } catch (e) {
100
+ alert(e);
101
+ alert(transport.responseText);
102
+ }
103
+ }.bind(this)
104
+ });
105
+ },
106
+
107
+ accountLogout: function() {
108
+ new Ajax.Request(this.lUrl, {
109
+ onSuccess: function(transport) {
110
+ try {
111
+ if (transport.responseText.isJSON()) {
112
+ var response = transport.responseText.evalJSON();
113
+ if (response.status == 'OK') {
114
+ window.location.reload();
115
+ return;
116
+ }
117
+ alert('Failed to logout. Please try again!');
118
+ }
119
+ } catch (e) {
120
+ alert(e);
121
+ alert(transport.responseText);
122
+ }
123
+ }.bind(this)
124
+ });
125
+ }
126
+ };
127
+
128
+ var Estimate = Class.create();
129
+ Estimate.prototype = {
130
+ initialize: function(store, urls) {
131
+ this.prepdata = urls.prepdata;
132
+ this.savedata = urls.savedata;
133
+ this.pushtext = urls.pushtext;
134
+ this.esttexts = urls.esttexts;
135
+
136
+ this.store = store;
137
+ this.language = $('translateto').value;
138
+ this.quality = $('est_qual').down().value;
139
+
140
+ this.loader_note = document
141
+ .createElement('small')
142
+ .writeAttribute('id', 'est_loader')
143
+ .writeAttribute('style', 'height: 26px; display: block; font-weight: normal; font-size: 11px; line-height: 13px; padding-top: 8px;');
144
+ },
145
+
146
+ prepareData: function() {
147
+ new Ajax.Request(this.prepdata, {
148
+ onLoading: function() {
149
+ this.loader_note.update('Preparing data...');
150
+ $('loading_mask_loader').insert(this.loader_note);
151
+ }.bind(this),
152
+ onSuccess: function(transport) {
153
+ var response = transport.responseText || "An error occurred: server did not send a response";
154
+ this.loader_note.update(response);
155
+ this.saveTextData();
156
+ }.bind(this)
157
+ });
158
+ },
159
+
160
+ saveTextData: function() {
161
+ new Ajax.Request(this.savedata, {
162
+ parameters : {
163
+ 'lang' : this.language,
164
+ 'qual' : this.quality,
165
+ 'store' : this.store
166
+ },
167
+ onSuccess: function(transport) {
168
+ var response = transport.responseText || "An error occurred: server did not send a response";
169
+ this.loader_note.update(response);
170
+ this.pushText();
171
+ }.bind(this)
172
+ });
173
+ },
174
+
175
+ pushText: function() {
176
+ new Ajax.Request(this.pushtext, {
177
+ parameters: {
178
+ 'lang' : this.language,
179
+ 'qual' : this.quality
180
+ },
181
+ onSuccess: function(transport) {
182
+ var response = transport.responseText || "An error occurred: server did not send a response";
183
+ this.loader_note.update(response);
184
+ this.estimateTexts();
185
+ }.bind(this)
186
+ });
187
+ },
188
+
189
+ estimateTexts: function() {
190
+ new Ajax.Request(this.esttexts, {
191
+ method: "post",
192
+ parameters: {
193
+ 'lang' : this.language,
194
+ 'qual' : this.quality,
195
+ 'store' : this.store
196
+ },
197
+ onSuccess: function(transport) {
198
+ var response = transport.responseText || "An error occurred: server did not send a response";
199
+ $('est_loader').remove();
200
+ $('estimation_result').update(response);
201
+ }.bind(this)
202
+ });
203
+ }
204
+ };
205
+
206
+ var PostEstimate = Class.create();
207
+ PostEstimate.prototype = {
208
+ initialize: function(urls) {
209
+ this.transl = urls.transl;
210
+ this.cancel = urls.cancel;
211
+ },
212
+
213
+ translateEstimated: function() {
214
+ new Ajax.Request(this.transl, {
215
+ onSuccess: function() {
216
+ window.location.reload();
217
+ }.bind(this),
218
+ onFailure: function() {
219
+ alert('Items were not translated!');
220
+ }.bind(this)
221
+ });
222
+ },
223
+
224
+ cancelEstimated: function() {
225
+ new Ajax.Request(this.cancel, {
226
+ onSuccess: function() {
227
+ window.location.reload();
228
+ }.bind(this),
229
+ onFailure: function() {
230
+ alert('Items were not deleted!');
231
+ }.bind(this)
232
+ });
233
+ }
234
+ };
235
+
236
+ function translateAll(url, store) {
237
+ new Ajax.Request(url, {
238
+ method: "post",
239
+ parameters: {
240
+ 'translate_store' : store,
241
+ 'translate_from' : $('translateto').value,
242
+ 'translate_quality' : $$('#est_qual .translate_quality')[0].value
243
+ },
244
+ onSuccess: function(transport) {
245
+ var response = transport.responseText || "An error occurred: server did not send a response";
246
+ $('estimation_result').update(response);
247
+ }
248
+ });
249
+ }
js/transfluent/lib.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * build select options from object
3
+ *
4
+ * @param obj
5
+ *
6
+ * @returns string
7
+ */
8
+ function buildSelectOptions(obj) {
9
+ var html = "";
10
+ for (var i = 0; i < obj.length; i++) {
11
+ html += '<option ';
12
+ html += (typeof(obj[i].name) !== 'undefined') ? " name=\"" + obj[i].name + "\" " : " ";
13
+ html += (typeof(obj[i].selected) !== 'undefined' && true == obj[i].selected) ? " selected='" + obj[i].selected + "' " : " ";
14
+ html += ">";
15
+ html += (typeof(obj[i].name) !== 'undefined') ? obj[i].name : "";
16
+ html += '</option>\n';
17
+ }
18
+ return html;
19
+ }
20
+
21
+ /**
22
+ * hides element
23
+ *
24
+ * @param id
25
+ *
26
+ * @returns {boolean}
27
+ */
28
+ function hideElementById(id) {
29
+ var element = document.getElementById(id);
30
+ element.style.display = 'none';
31
+ return true;
32
+ }
33
+
34
+ /**
35
+ * show a dom element
36
+ *
37
+ * @param id
38
+ *
39
+ * @returns {boolean}
40
+ */
41
+ function showElementById(id) {
42
+ var element = document.getElementById(id);
43
+ if (!element)
44
+ return false;
45
+
46
+ element.style.display = null;
47
+ return true;
48
+ }
49
+
50
+ /**
51
+ * returns array of products from selected groups
52
+ *
53
+ * @returns {Array}
54
+ */
55
+ function getSelectedProducts(checkboxGroup) {
56
+ var productIds = [];
57
+ var checkboxes = document.getElementsByName(checkboxGroup);
58
+ var categoryId, products;
59
+ for (var i = 0; i < checkboxes.length; i++) {
60
+
61
+ if (checkboxes[i].checked == true) {
62
+ categoryId = checkboxes[i].value;
63
+ for (var j = 0; j < categoryProducts[categoryId].length; j++)
64
+ productIds.push(categoryProducts[categoryId][j]);
65
+ }
66
+ }
67
+ return productIds;
68
+ }
package.xml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Transfluent</name>
4
+ <version>1.2.0</version>
5
+ <stability>stable</stability>
6
+ <license>MIT</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Want to add another language to your ecommerce site? Transfluent supports Magento, the leading ecommerce solution.&#xD;
10
+ &#xD;
11
+ You can translate your entire catalog of products once, effortlessly! Just choose which languages to target and we take care of the rest. When you later add new products or make changes to the existing ones, the translations will be updated as well.&#xD;
12
+ &#xD;
13
+ Just install the plugin and do a one-time account setup, and you&#x2019;re all set. You will be billed monthly for all the translations made, based on the number of words and the service level you choose.&#xD;
14
+ &#xD;
15
+ &lt;a href="https://tf-wordpress.s3.amazonaws.com/wp-content/uploads/2014/01/TF-Magento-Getting_started.pdf"&gt;Download Getting started guide&lt;/a&gt;&#xD;
16
+ </summary>
17
+ <description>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.&#xD;
18
+ &#xD;
19
+ Translating content is handled in our backend using a vast network of professional translators.</description>
20
+ <notes>Added feature for translating whole categories in one order.</notes>
21
+ <authors><author><name>Ilari M&#xE4;kimattila</name><user>kryil</user><email>ilari@transfluent.com</email></author></authors>
22
+ <date>2014-06-27</date>
23
+ <time>10:07:16</time>
24
+ <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="5ad0a404b911c983472a9e5b6a1a2d02"/><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="6f8dd70bc812d0295a32b4086f0a33ef"/><file name="Regform.php" hash="1322ad01684df93ccf2509ab2a175e3b"/><file name="Translblock.php" hash="8008b680d4bdbeb7b2e51a3522ac282a"/></dir><dir name="Exception"><file name="Base.php" hash="e0ab547033d95d94820a5cbd58dea6f5"/><file name="EBackendCustomerHasNoBillingAgreement.php" hash="99c53cf99452b6042654b792cc8c7e27"/><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="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="1027dc867c0f3d3f1f09165835e372af"/><file name="Constant.php" hash="76af7760107c984a86a8522d08f33529"/><file name="Data.php" hash="115f604df2570d512d73c45eb272588b"/><file name="Languages.php" hash="09d6e47be8a5c60c529ca527f2651680"/><file name="Product.php" hash="ee04f0c62cdeef260c677cd1fc363041"/><file name="Tag.php" hash="aba096e9a6207e7f2055db4733c1b839"/><file name="Text.php" hash="4e5c084ac4e849d6fe2614dfef77c932"/><file name="Util.php" hash="cef5322b0b36f8e117f30e35e01ce2d7"/></dir><dir name="Model"><file name="AttributeName.php" hash="97619966fb9c04b031d2cae5147fdb21"/><file name="AttributeOption.php" hash="39007a2e2821e5853b6cfefe0e1a1c17"/><dir name="Base"><file name="Backendclient.php" hash="b6066b416a2594406af70119f6a955b0"/></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="a83033eaa72937acb084672ce2616c7e"/><file name="TransfluenttranslateController.php" hash="6f024d5b54b7cbf6cf2618a6831932d5"/></dir><file name="TranslationController.php" hash="6557858166c035ccf2ee9653df39ce6a"/></dir><dir name="etc"><file name="config.xml" hash="ae06834805c8d02f1389cab8eac8c203"/><file name="system.xml" hash="2e75d28da153fcc0933b7a6a262195fd"/></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="order.phtml" hash="54294374fb3de509a2bd2cddbcf15474"/></dir><dir name="product"><dir name="attributes"><file name="edit.phtml" hash="3d0fc11a2f436770f735429f5852306a"/></dir><dir name="category"><file name="edit.phtml" hash="b9dd037f74495a3132bddde6f7c615fe"/></dir><file name="edit.phtml" hash="1bb1a5773e841f1eedbecfecd4dffa1e"/><file name="index.phtml" hash="7ea9b53f06a8045e19d4727c41059d58"/></dir><dir name="tag"><dir name="tag"><file name="index.phtml" hash="ad31bc62c63f2c85ce9143186ec655a2"/></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>
25
+ <compatible/>
26
+ <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><extension><name>mbstring</name><min></min><max></max></extension></required></dependencies>
27
+ </package>