smartling - Version 1.0.0

Version Notes

Stable version

Download this release

Release Info

Developer Dmitriy Studinskiy
Extension smartling
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (185) hide show
  1. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/AbstractEavGrid.php +82 -0
  2. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Attributes.php +26 -0
  3. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Attributes/Grid.php +49 -0
  4. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/Observer.php +27 -0
  5. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/TranslateExisting.php +46 -0
  6. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/Translations.php +143 -0
  7. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes.php +26 -0
  8. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes/Edit/Tab/Translations.php +45 -0
  9. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes/Grid.php +48 -0
  10. app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Edit/Tab/Translations.php +56 -0
  11. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/AbstractFlatGrid.php +83 -0
  12. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Form.php +31 -0
  13. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Translations.php +37 -0
  14. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Translations/Fieldset.php +25 -0
  15. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Fields.php +26 -0
  16. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Fields/Grid.php +35 -0
  17. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Edit/Tab/Translations.php +107 -0
  18. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Fields.php +26 -0
  19. app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Fields/Grid.php +36 -0
  20. app/code/community/Smartling/Connector/Block/Adminhtml/Content.php +19 -0
  21. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Attribute.php +49 -0
  22. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Attribute/Grid.php +118 -0
  23. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Category.php +38 -0
  24. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Category/Grid.php +167 -0
  25. app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsBlock.php +39 -0
  26. app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsBlock/Grid.php +226 -0
  27. app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsPage.php +39 -0
  28. app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsPage/Grid.php +230 -0
  29. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Grid.php +218 -0
  30. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Grid/Column/Status.php +69 -0
  31. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Localization.php +39 -0
  32. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Localization/Grid.php +200 -0
  33. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Product.php +49 -0
  34. app/code/community/Smartling/Connector/Block/Adminhtml/Content/Product/Grid.php +288 -0
  35. app/code/community/Smartling/Connector/Block/Adminhtml/Edit/Tab/Translations.php +173 -0
  36. app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Download.php +32 -0
  37. app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Link.php +33 -0
  38. app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Progress.php +37 -0
  39. app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Massaction.php +47 -0
  40. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Edit.php +27 -0
  41. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Edit/Form.php +39 -0
  42. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Attribute.php +49 -0
  43. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Category.php +57 -0
  44. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/CmsBlock.php +49 -0
  45. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/CmsPage.php +49 -0
  46. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Default.php +50 -0
  47. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Localization.php +49 -0
  48. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Product.php +58 -0
  49. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tabs.php +71 -0
  50. app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Widget.php +48 -0
  51. app/code/community/Smartling/Connector/Block/Adminhtml/Localization/Files/Edit/Form.php +39 -0
  52. app/code/community/Smartling/Connector/Block/Adminhtml/Logs/View.php +51 -0
  53. app/code/community/Smartling/Connector/Block/Adminhtml/Logs/View/Grid.php +88 -0
  54. app/code/community/Smartling/Connector/Block/Adminhtml/Projects.php +25 -0
  55. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit.php +35 -0
  56. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form.php +29 -0
  57. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form/Element/Profiles.php +55 -0
  58. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form/Element/StoreViewLabel.php +73 -0
  59. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Tabs.php +23 -0
  60. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Tabs/Form.php +129 -0
  61. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Grid.php +139 -0
  62. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Locales/Form.php +135 -0
  63. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New.php +20 -0
  64. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Form.php +29 -0
  65. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Form/Element/StoreViewLabel.php +73 -0
  66. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Tabs.php +24 -0
  67. app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Tabs/Form.php +52 -0
  68. app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/ConnectionButton.php +50 -0
  69. app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/ContentFields.php +109 -0
  70. app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/Version.php +20 -0
  71. app/code/community/Smartling/Connector/Helper/Data.php +613 -0
  72. app/code/community/Smartling/Connector/Model/Content.php +153 -0
  73. app/code/community/Smartling/Connector/Model/Content/Abstract.php +481 -0
  74. app/code/community/Smartling/Connector/Model/Content/Attribute.php +324 -0
  75. app/code/community/Smartling/Connector/Model/Content/Attributes/Builder.php +52 -0
  76. app/code/community/Smartling/Connector/Model/Content/Attributes/Options.php +68 -0
  77. app/code/community/Smartling/Connector/Model/Content/Category.php +226 -0
  78. app/code/community/Smartling/Connector/Model/Content/Category/Observer.php +74 -0
  79. app/code/community/Smartling/Connector/Model/Content/CmsBlock.php +280 -0
  80. app/code/community/Smartling/Connector/Model/Content/CmsBlock/Observer.php +67 -0
  81. app/code/community/Smartling/Connector/Model/Content/CmsPage.php +275 -0
  82. app/code/community/Smartling/Connector/Model/Content/CmsPage/Observer.php +66 -0
  83. app/code/community/Smartling/Connector/Model/Content/EavEntityInterface.php +9 -0
  84. app/code/community/Smartling/Connector/Model/Content/Interface.php +52 -0
  85. app/code/community/Smartling/Connector/Model/Content/Localization.php +336 -0
  86. app/code/community/Smartling/Connector/Model/Content/Product.php +255 -0
  87. app/code/community/Smartling/Connector/Model/Content/Product/Observer.php +72 -0
  88. app/code/community/Smartling/Connector/Model/Content/Types.php +33 -0
  89. app/code/community/Smartling/Connector/Model/Localization/Files.php +205 -0
  90. app/code/community/Smartling/Connector/Model/Localization/Files/Index.php +19 -0
  91. app/code/community/Smartling/Connector/Model/Localization/Files/Observer.php +76 -0
  92. app/code/community/Smartling/Connector/Model/Projects.php +145 -0
  93. app/code/community/Smartling/Connector/Model/Projects/Filter.php +47 -0
  94. app/code/community/Smartling/Connector/Model/Projects/Filter/Attribute.php +12 -0
  95. app/code/community/Smartling/Connector/Model/Projects/Filter/Category.php +51 -0
  96. app/code/community/Smartling/Connector/Model/Projects/Filter/CmsBlock.php +12 -0
  97. app/code/community/Smartling/Connector/Model/Projects/Filter/CmsPage.php +47 -0
  98. app/code/community/Smartling/Connector/Model/Projects/Filter/Localization.php +58 -0
  99. app/code/community/Smartling/Connector/Model/Projects/Filter/Product.php +48 -0
  100. app/code/community/Smartling/Connector/Model/Projects/Locales.php +65 -0
  101. app/code/community/Smartling/Connector/Model/Request.php +165 -0
  102. app/code/community/Smartling/Connector/Model/Resource/Content.php +150 -0
  103. app/code/community/Smartling/Connector/Model/Resource/Content/Collection.php +75 -0
  104. app/code/community/Smartling/Connector/Model/Resource/Content/Types.php +19 -0
  105. app/code/community/Smartling/Connector/Model/Resource/Content/Types/Collection.php +12 -0
  106. app/code/community/Smartling/Connector/Model/Resource/Localization/Files/Index.php +18 -0
  107. app/code/community/Smartling/Connector/Model/Resource/Localization/Files/Index/Collection.php +14 -0
  108. app/code/community/Smartling/Connector/Model/Resource/Log/Collection.php +138 -0
  109. app/code/community/Smartling/Connector/Model/Resource/Projects.php +19 -0
  110. app/code/community/Smartling/Connector/Model/Resource/Projects/Collection.php +15 -0
  111. app/code/community/Smartling/Connector/Model/Resource/Projects/Locales.php +19 -0
  112. app/code/community/Smartling/Connector/Model/Resource/Projects/Locales/Collection.php +15 -0
  113. app/code/community/Smartling/Connector/Model/Resource/Translate/Attributes.php +20 -0
  114. app/code/community/Smartling/Connector/Model/Resource/Translate/Attributes/Collection.php +15 -0
  115. app/code/community/Smartling/Connector/Model/Resource/Translate/Fields.php +20 -0
  116. app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/Collection.php +15 -0
  117. app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Block/Collection.php +15 -0
  118. app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Collection.php +127 -0
  119. app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Page/Collection.php +14 -0
  120. app/code/community/Smartling/Connector/Model/Service.php +440 -0
  121. app/code/community/Smartling/Connector/Model/Service/Observer.php +100 -0
  122. app/code/community/Smartling/Connector/Model/SmartlingAPI.php +239 -0
  123. app/code/community/Smartling/Connector/Model/Source/Content/Attributes/Category.php +42 -0
  124. app/code/community/Smartling/Connector/Model/Source/Content/Attributes/Product.php +41 -0
  125. app/code/community/Smartling/Connector/Model/Source/Content/Fields/CmsBlock.php +29 -0
  126. app/code/community/Smartling/Connector/Model/Source/Content/Fields/CmsPage.php +30 -0
  127. app/code/community/Smartling/Connector/Model/Source/Content/Status.php +21 -0
  128. app/code/community/Smartling/Connector/Model/Source/Content/Stores.php +37 -0
  129. app/code/community/Smartling/Connector/Model/Source/Content/Types.php +67 -0
  130. app/code/community/Smartling/Connector/Model/Source/Log/Level.php +29 -0
  131. app/code/community/Smartling/Connector/Model/Source/Projects.php +72 -0
  132. app/code/community/Smartling/Connector/Model/Source/Stores.php +51 -0
  133. app/code/community/Smartling/Connector/Model/Source/Types.php +27 -0
  134. app/code/community/Smartling/Connector/Model/Source/Websites.php +36 -0
  135. app/code/community/Smartling/Connector/Model/Translate/Attributes.php +35 -0
  136. app/code/community/Smartling/Connector/Model/Translate/Fields.php +19 -0
  137. app/code/community/Smartling/Connector/Model/Translate/StatusInterface.php +15 -0
  138. app/code/community/Smartling/Connector/Model/Translator.php +597 -0
  139. app/code/community/Smartling/Connector/Model/Translator/Observer.php +51 -0
  140. app/code/community/Smartling/Connector/Model/Types/Abstract.php +38 -0
  141. app/code/community/Smartling/Connector/Model/Types/Content.php +25 -0
  142. app/code/community/Smartling/Connector/Model/Types/General.php +23 -0
  143. app/code/community/Smartling/Connector/Model/Types/Htmlcontent.php +25 -0
  144. app/code/community/Smartling/Connector/Model/Types/List.php +46 -0
  145. app/code/community/Smartling/Connector/Model/Types/Xml.php +467 -0
  146. app/code/community/Smartling/Connector/controllers/Adminhtml/AttributesController.php +52 -0
  147. app/code/community/Smartling/Connector/controllers/Adminhtml/FieldsController.php +52 -0
  148. app/code/community/Smartling/Connector/controllers/Adminhtml/InstanceController.php +291 -0
  149. app/code/community/Smartling/Connector/controllers/Adminhtml/ProjectsController.php +214 -0
  150. app/code/community/Smartling/Connector/controllers/Adminhtml/ServiceController.php +112 -0
  151. app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CategoryController.php +31 -0
  152. app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CmsBlockController.php +28 -0
  153. app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CmsPageController.php +31 -0
  154. app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/LocalizationController.php +29 -0
  155. app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/ProductController.php +27 -0
  156. app/code/community/Smartling/Connector/controllers/Adminhtml/TranslatorController.php +616 -0
  157. app/code/community/Smartling/Connector/controllers/ServiceController.php +143 -0
  158. app/code/community/Smartling/Connector/etc/adminhtml.xml +115 -0
  159. app/code/community/Smartling/Connector/etc/config.xml +315 -0
  160. app/code/community/Smartling/Connector/etc/system.xml +101 -0
  161. app/code/community/Smartling/Connector/sql/smartling_setup/install-1.0.0.php +291 -0
  162. app/design/adminhtml/default/default/layout/smartling/translator.xml +212 -0
  163. app/design/adminhtml/default/default/template/connector/adminhtml/edit/tab/bulk_translations.phtml +60 -0
  164. app/design/adminhtml/default/default/template/connector/adminhtml/edit/tab/translations.phtml +117 -0
  165. app/design/adminhtml/default/default/template/connector/adminhtml/logs/view.phtml +13 -0
  166. app/design/adminhtml/default/default/template/connector/adminhtml/system/config/connectionbutton.phtml +33 -0
  167. app/design/adminhtml/default/default/template/connector/adminhtml/system/config/contentfields.phtml +14 -0
  168. app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/massaction.phtml +86 -0
  169. app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/scripts_wraper.phtml +7 -0
  170. app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/translate_status.phtml +11 -0
  171. app/etc/modules/Smartling_Connector.xml +10 -0
  172. js/smartling/check_statuses.js +90 -0
  173. js/smartling/content.js +17 -0
  174. js/smartling/locales_bulk_validation.js +13 -0
  175. js/smartling/locales_validation.js +13 -0
  176. js/smartling/select_all.js +20 -0
  177. lib/SmartlingApi/lib/HttpClient.php +320 -0
  178. lib/SmartlingApi/lib/SmartlingAPI.php +220 -0
  179. package.xml +29 -0
  180. skin/adminhtml/default/default/smartling/StyleSheet/bars.css +19 -0
  181. skin/adminhtml/default/default/smartling/images/changed.png +0 -0
  182. skin/adminhtml/default/default/smartling/images/inprogress.png +0 -0
  183. skin/adminhtml/default/default/smartling/images/sm_loader.gif +0 -0
  184. skin/adminhtml/default/default/smartling/images/translated.png +0 -0
  185. skin/adminhtml/default/default/smartling/images/wait.png +0 -0
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/AbstractEavGrid.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ abstract class Smartling_Connector_Block_Adminhtml_Catalog_AbstractEavGrid
10
+ extends Mage_Eav_Block_Adminhtml_Attribute_Grid_Abstract
11
+ {
12
+ /**
13
+ *
14
+ * @var string - Smartling type name
15
+ */
16
+ protected $_typeName;
17
+
18
+ public function __construct()
19
+ {
20
+ parent::__construct();
21
+ $this->setId('attributeGrid');
22
+ $this->setDefaultSort('attribute_code');
23
+ $this->setDefaultDir('ASC');
24
+ }
25
+
26
+ /**
27
+ * Prepare product attributes grid columns
28
+ *
29
+ * @return Smartling_Connector_Block_Adminhtml_Catalog_AbstractEavGrid
30
+ */
31
+ protected function _prepareColumns()
32
+ {
33
+
34
+ $this->addColumn('is_attached', array(
35
+ 'header'=>Mage::helper('connector')->__('Translate'),
36
+ 'sortable'=>true,
37
+ 'index'=>'is_attached',
38
+ 'width' => '20px',
39
+ 'align' => 'center',
40
+ 'renderer' => 'Smartling_Connector_Block_Adminhtml_Content_Grid_Column_Status',
41
+ 'filter' => false,
42
+ 'options' => array(
43
+ '1' => Mage::helper('connector')->__('Yes'),
44
+ '0' => Mage::helper('connector')->__('No'),
45
+ ),
46
+ ));
47
+
48
+ $this->addColumn('attribute_code', array(
49
+ 'header'=>Mage::helper('eav')->__('Attribute Code'),
50
+ 'sortable'=>true,
51
+ 'index'=>'attribute_code',
52
+ 'width' => '250px',
53
+ ));
54
+
55
+ $this->addColumn('frontend_label', array(
56
+ 'header'=>Mage::helper('eav')->__('Attribute Label'),
57
+ 'sortable'=>true,
58
+ 'index'=>'frontend_label'
59
+ ));
60
+
61
+ return $this;
62
+ }
63
+
64
+ /**
65
+ * Return url of given row
66
+ *
67
+ * @return string
68
+ */
69
+ public function getRowUrl($model)
70
+ {
71
+ return false;
72
+ }
73
+
74
+ /**
75
+ *
76
+ * @return int
77
+ */
78
+ public function getContentTypeId() {
79
+ $type = Mage::getModel('connector/content_types')->getTypeDetails($this->_typeName);
80
+ return $type->getTypeId();
81
+ }
82
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Attributes.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Category_Attributes
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_catalog_category_attributes";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('Category Attributes');
17
+
18
+ parent::__construct();
19
+ $this->_removeButton('add');
20
+ }
21
+
22
+ public function getCreateUrl()
23
+ {
24
+ return false;
25
+ }
26
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Attributes/Grid.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Category attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Catalog_Category_Attributes_Grid
10
+ extends Smartling_Connector_Block_Adminhtml_Catalog_AbstractEavGrid
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ $this->_typeName = 'category';
16
+ parent::__construct();
17
+ $this->setId('categoryAttributesGrid');
18
+ }
19
+
20
+ /**
21
+ * Prepare product attributes grid collection object
22
+ *
23
+ * @return Mage_Adminhtml_Block_Catalog_Category_Attribute_Grid
24
+ */
25
+ protected function _prepareCollection()
26
+ {
27
+ $resource = Mage::getModel('core/resource');
28
+ $systemAttributes = array_keys(Mage::getStoreConfig('connector/translate_attributes/catalog_category'));
29
+ $type = Mage::getModel('connector/content_types')->getTypeDetails($this->_typeName);
30
+ $content_types_id = $type->getTypeId();
31
+
32
+ $collection = Mage::getResourceModel('catalog/category_attribute_collection')
33
+ ->addFieldToFilter('is_global', Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE)
34
+ ->addFieldToFilter('attribute_code', array('nin' => $systemAttributes));
35
+
36
+ $collection->getSelect()
37
+ ->joinLeft(
38
+ array('ia' => $resource->getTableName('connector/translate_attributes')),
39
+ 'ia.attribute_id = main_table.attribute_id and ia.entity_type_id = ' . (int)$content_types_id,
40
+ array('is_attached' => new Zend_Db_Expr('IF(ia.id > 0, 1, 0)'))
41
+ );
42
+
43
+
44
+
45
+ $this->setCollection($collection);
46
+
47
+ return parent::_prepareCollection();
48
+ }
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/Observer.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Category_Tab_Observer
9
+ {
10
+
11
+ public function addTranslationTab(Varien_Event_Observer $object){
12
+ $tabs = $object->getEvent()->getTabs();
13
+ $categoryId = Mage::app()->getRequest()->getParam('id');
14
+ $blockClass = 'translateExisting';
15
+
16
+ if (Mage::helper('connector')->showTranslationTab()){
17
+ $tabs->addTab('translator', array(
18
+ 'label' => Mage::helper('connector')->__('Smartling Translator'),
19
+ 'content' => Mage::app()->getLayout()->createBlock(
20
+ "connector/adminhtml_catalog_category_tab_{$blockClass}",
21
+ 'category.translations.grid'
22
+ )->toHtml(),
23
+ ));
24
+ }
25
+ }
26
+
27
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/TranslateExisting.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Category_Tab_TranslateExisting
9
+ extends Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId = 4;
17
+
18
+ /**
19
+ * Returns status flag about this tab can be shown or not
20
+ *
21
+ * @return true
22
+ */
23
+ public function canShowTab()
24
+ {
25
+ return Mage::helper('connector')->showTranslationTab();
26
+ }
27
+
28
+ /**
29
+ * Check permission for passed action
30
+ *
31
+ * @param string $action
32
+ * @return bool
33
+ */
34
+ protected function _isAllowedAction($action)
35
+ {
36
+ return Mage::getSingleton('admin/session')->isAllowed('catalog/category/' . $action);
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @return int
42
+ */
43
+ public function getContentId() {
44
+ return Mage::app()->getRequest()->getParam('id');
45
+ }
46
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Category/Tab/Translations.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Tranlsations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Category_Tab_Translations
9
+ extends Mage_Adminhtml_Block_Widget_Form
10
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
11
+ {
12
+
13
+ protected $_category;
14
+
15
+ public function __construct()
16
+ {
17
+ if (!Mage::helper('connector')->showTranslationTab()){
18
+ return;
19
+ }
20
+ parent::__construct();
21
+ $this->setShowGlobalIcon(true);
22
+
23
+ }
24
+
25
+ public function getCategory()
26
+ {
27
+ if (!$this->_category) {
28
+ $this->_category = Mage::registry('category');
29
+ }
30
+ return $this->_category;
31
+ }
32
+
33
+ protected function _prepareForm(){
34
+ /*
35
+ * Checking if user have permissions to save information
36
+ */
37
+ if ($this->_isAllowedAction('edit')) {
38
+ $isElementDisabled = false;
39
+ } else {
40
+ $isElementDisabled = true;
41
+ }
42
+
43
+ $form = new Varien_Data_Form();
44
+
45
+ $form->setHtmlIdPrefix('translations_');
46
+
47
+ $fieldset = $form->addFieldset('smartling_translation', array(
48
+ 'legend'=>Mage::helper('connector')->__('Smartling Translation')
49
+ ));
50
+
51
+ $fieldset->addField('translation_is_active', 'select', array(
52
+ 'label' => Mage::helper('connector')->__('Enable Smartling Translations'),
53
+ 'title' => Mage::helper('connector')->__('Enable Smartling Translations'),
54
+ 'name' => 'general[translation_is_active]',
55
+ 'required' => true,
56
+ 'options' => array(
57
+ '1' => Mage::helper('connector')->__('Enabled'),
58
+ '0' => Mage::helper('connector')->__('Disabled'),
59
+ ),
60
+ 'disabled' => $isElementDisabled,
61
+ ));
62
+
63
+ /**
64
+ * Check is single store mode
65
+ */
66
+ if (!Mage::app()->isSingleStoreMode()) {
67
+ $field = $fieldset->addField('translate_store_id', 'multiselect', array(
68
+ 'name' => 'general[translate_stores][]',
69
+ 'label' => Mage::helper('cms')->__('Store View'),
70
+ 'title' => Mage::helper('cms')->__('Store View'),
71
+ 'required' => false,
72
+ 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, false),
73
+ 'disabled' => $isElementDisabled,
74
+ ));
75
+ $renderer = $this->getLayout()->createBlock('adminhtml/store_switcher_form_renderer_fieldset_element');
76
+ $field->setRenderer($renderer);
77
+ }
78
+ else {
79
+ $fieldset->addField('translate_store_id', 'hidden', array(
80
+ 'name' => 'general[translate_stores][]',
81
+ 'value' => Mage::app()->getStore(true)->getId()
82
+ ));
83
+ $this->getCategory()->setStoreId(Mage::app()->getStore(true)->getId());
84
+ }
85
+
86
+ $form->addValues($this->getCategory()->getData());
87
+ $this->setForm($form);
88
+
89
+ return parent::_prepareForm();
90
+ }
91
+
92
+ /**
93
+ * Prepare label for tab
94
+ *
95
+ * @return string
96
+ */
97
+ public function getTabLabel()
98
+ {
99
+ return Mage::helper('connector')->__('Smartling Translations');
100
+ }
101
+
102
+ /**
103
+ * Prepare title for tab
104
+ *
105
+ * @return string
106
+ */
107
+ public function getTabTitle()
108
+ {
109
+ Mage::helper('connector')->showTranslationTab();
110
+ return Mage::helper('connector')->__('Smartling Translations');
111
+ }
112
+
113
+ /**
114
+ * Returns status flag about this tab can be shown or not
115
+ *
116
+ * @return true
117
+ */
118
+ public function canShowTab()
119
+ {
120
+ return Mage::helper('connector')->showTranslationTab();
121
+ }
122
+
123
+ /**
124
+ * Returns status flag about this tab hidden or not
125
+ *
126
+ * @return true
127
+ */
128
+ public function isHidden()
129
+ {
130
+ return false;
131
+ }
132
+
133
+ /**
134
+ * Check permission for passed action
135
+ *
136
+ * @param string $action
137
+ * @return bool
138
+ */
139
+ protected function _isAllowedAction($action)
140
+ {
141
+ return Mage::getSingleton('admin/session')->isAllowed('catalog/category/' . $action);
142
+ }
143
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Product_Attributes
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_catalog_product_attributes";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('Products Attributes');
17
+
18
+ parent::__construct();
19
+ $this->_removeButton('add');
20
+ }
21
+
22
+ public function getCreateUrl()
23
+ {
24
+ return false;
25
+ }
26
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes/Edit/Tab/Translations.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Product_Attributes_Edit_Tab_Translations
9
+ extends Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId = 5;
17
+
18
+ /**
19
+ *
20
+ * @return string | Mage_Adminhtml_Block_Widget_Form
21
+ * @return true
22
+ */
23
+ public function canShowTab() {
24
+ return true;
25
+ }
26
+
27
+ /**
28
+ * Check permission for passed action
29
+ *
30
+ * @param string $action
31
+ * @return bool
32
+ */
33
+ protected function _isAllowedAction($action) {
34
+ return true;
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @return int
40
+ */
41
+ public function getContentId() {
42
+ return Mage::app()->getRequest()->getParam('attribute_id');
43
+ }
44
+
45
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Attributes/Grid.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Catalog_Product_Attributes_Grid
10
+ extends Smartling_Connector_Block_Adminhtml_Catalog_AbstractEavGrid
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ $this->_typeName = 'product';
16
+ parent::__construct();
17
+ $this->setId('productAttributesGrid');
18
+ }
19
+
20
+ /**
21
+ * Prepare product attributes grid collection object
22
+ *
23
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
24
+ */
25
+ protected function _prepareCollection()
26
+ {
27
+ $resource = Mage::getModel('core/resource');
28
+ $systemAttributes = array_keys(Mage::getStoreConfig('connector/translate_attributes/catalog_product'));
29
+ $type = Mage::getModel('connector/content_types')->getTypeDetails($this->_typeName);
30
+ $content_types_id = $type->getTypeId();
31
+
32
+ $collection = Mage::getResourceModel('catalog/product_attribute_collection')
33
+ ->addVisibleFilter()
34
+ ->addFieldToFilter('is_global', Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE)
35
+ ->addFieldToFilter('attribute_code', array('nin' => $systemAttributes));
36
+
37
+ $collection->getSelect()
38
+ ->joinLeft(
39
+ array('ia' => $resource->getTableName('connector/translate_attributes')),
40
+ 'ia.attribute_id = main_table.attribute_id and ia.entity_type_id = ' . (int)$content_types_id,
41
+ array('is_attached' => new Zend_Db_Expr('IF(ia.id > 0, 1, 0)'))
42
+ );
43
+
44
+ $this->setCollection($collection);
45
+
46
+ return parent::_prepareCollection();
47
+ }
48
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Catalog/Product/Edit/Tab/Translations.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Catalog_Product_Edit_Tab_Translations
9
+ extends Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId = 3;
17
+
18
+ public function __construct() {
19
+ parent::__construct();
20
+
21
+ $contentId = $this->getContentId();
22
+ $product = Mage::getSingleton('catalog/product')->load($contentId);
23
+
24
+ $websites = $product->getWebsiteIds();
25
+ $websites[] = -1; // prevent case when no one website was selected
26
+ $this->setWebsites($websites);
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @return string | Mage_Adminhtml_Block_Widget_Form *
32
+ * @return true
33
+ */
34
+ public function canShowTab() {
35
+ return Mage::helper('connector')->showTranslationTab();
36
+ }
37
+
38
+ /**
39
+ * Check permission for passed action
40
+ *
41
+ * @param string $action
42
+ * @return bool
43
+ */
44
+ protected function _isAllowedAction($action) {
45
+ return Mage::getSingleton('admin/session')->isAllowed('catalog/product/' . $action);
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @return int
51
+ */
52
+ public function getContentId() {
53
+ return Mage::app()->getRequest()->getParam('id');
54
+ }
55
+
56
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/AbstractFlatGrid.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ abstract class Smartling_Connector_Block_Adminhtml_Cms_AbstractFlatGrid
10
+ extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+
13
+ /**
14
+ *
15
+ * @var string - Smartling type name
16
+ */
17
+ protected $_typeName;
18
+
19
+
20
+ public function __construct()
21
+ {
22
+ parent::__construct();
23
+ $this->setDefaultSort('id');
24
+ $this->setDefaultDir('ASC');
25
+ }
26
+
27
+ /**
28
+ * Prepare product attributes grid columns
29
+ *
30
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
31
+ */
32
+ protected function _prepareColumns()
33
+ {
34
+
35
+ $this->addColumn('is_attached', array(
36
+ 'header'=>Mage::helper('connector')->__('Translate'),
37
+ 'sortable'=>true,
38
+ 'index'=>'is_attached',
39
+ 'width' => '20px',
40
+ 'align' => 'center',
41
+ 'renderer' => 'Smartling_Connector_Block_Adminhtml_Content_Grid_Column_Status',
42
+ 'filter' => false,
43
+ 'options' => array(
44
+ '1' => Mage::helper('connector')->__('Yes'),
45
+ '0' => Mage::helper('connector')->__('No'),
46
+ ),
47
+ ));
48
+
49
+ $this->addColumn('id', array(
50
+ 'header'=>Mage::helper('eav')->__('Field Name'),
51
+ 'sortable'=>true,
52
+ 'index'=>'id',
53
+ 'width' => '250px',
54
+ ));
55
+
56
+ $this->addColumn('text', array(
57
+ 'header'=>Mage::helper('eav')->__('Field Description'),
58
+ 'sortable'=>true,
59
+ 'index'=>'text'
60
+ ));
61
+
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Return url of given row
67
+ *
68
+ * @return string
69
+ */
70
+ public function getRowUrl($model)
71
+ {
72
+ return false;
73
+ }
74
+
75
+ /**
76
+ *
77
+ * @return int
78
+ */
79
+ public function getContentTypeId() {
80
+ $type = Mage::getModel('connector/content_types')->getTypeDetails($this->_typeName);
81
+ return $type->getTypeId();
82
+ }
83
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Form.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Form
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Block_Edit_Form
9
+ extends Mage_Adminhtml_Block_Cms_Block_Edit_Form
10
+ {
11
+
12
+ protected function _prepareForm()
13
+ {
14
+ parent::_prepareForm();
15
+
16
+ $form = $this->getForm();
17
+
18
+ $fieldsetTranslation = $form->addFieldset('smartling',
19
+ array('legend'=> Mage::helper('connector')->__('Smartling Translations'),
20
+ 'class' => 'fieldset-wide')
21
+ );
22
+
23
+ $fieldsetTranslation->addType('translations', 'Smartling_Connector_Block_Adminhtml_Cms_Block_Edit_Translations');
24
+ $field = $fieldsetTranslation->addField('translations', 'translations', array(
25
+ 'label' => Mage::helper('connector')->__('Translations'),
26
+ 'title' => Mage::helper('connector')->__('Translations')
27
+ ));
28
+
29
+ return Mage_Adminhtml_Block_Widget_Form::_prepareForm();
30
+ }
31
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Translations.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Block_Edit_Translations
9
+ extends Varien_Data_Form_Element_Abstract
10
+ {
11
+ public function __construct($attributes=array())
12
+ {
13
+ parent::__construct($attributes);
14
+ $this->setType('label');
15
+ }
16
+
17
+ /**
18
+ *
19
+ * @return string
20
+ */
21
+ public function getElementHtml()
22
+ {
23
+ return '';
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @param string $idSuffix
29
+ * @return string
30
+ */
31
+ public function getLabelHtml($idSuffix = '') {
32
+
33
+ $translations = Mage::app()->getLayout()
34
+ ->createBlock('connector/adminhtml_cms_block_edit_translations_fieldset');
35
+ return $translations->toHtml();
36
+ }
37
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Edit/Translations/Fieldset.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Block_Edit_Translations_Fieldset
9
+ extends Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId = 2;
17
+
18
+ /**
19
+ *
20
+ * @return int
21
+ */
22
+ public function getContentId() {
23
+ return Mage::app()->getRequest()->getParam('block_id');
24
+ }
25
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Fields.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Block_Fields
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_cms_block_fields";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('CMS Block Fields');
17
+
18
+ parent::__construct();
19
+ $this->_removeButton('add');
20
+ }
21
+
22
+ public function getCreateUrl()
23
+ {
24
+ return false;
25
+ }
26
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Block/Fields/Grid.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Cms_Block_Fields_Grid
10
+ extends Smartling_Connector_Block_Adminhtml_Cms_AbstractFlatGrid
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ $this->_typeName = 'cmsBlock';
16
+
17
+ parent::__construct();
18
+ $this->setId('cmsBlockGrid');
19
+ }
20
+
21
+ /**
22
+ * Prepare product attributes grid collection object
23
+ *
24
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
25
+ */
26
+ protected function _prepareCollection()
27
+ {
28
+
29
+ $collection = Mage::getResourceModel('connector/translate_fields_list_block_collection');
30
+
31
+ $this->setCollection($collection);
32
+
33
+ return parent::_prepareCollection();
34
+ }
35
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Edit/Tab/Translations.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Tranlsations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Page_Edit_Tab_Translations
9
+ extends Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId = 1;
17
+
18
+
19
+ /**
20
+ * Prepare label for tab
21
+ *
22
+ * @return string
23
+ */
24
+ public function getTabLabel()
25
+ {
26
+ return Mage::helper('connector')->__('Smartling Translations');
27
+ }
28
+
29
+ /**
30
+ * Prepare title for tab
31
+ *
32
+ * @return string
33
+ */
34
+ public function getTabTitle()
35
+ {
36
+ return Mage::helper('cms')->__('Smartling Translations');
37
+ }
38
+
39
+ /**
40
+ * Returns status flag about this tab can be shown or not
41
+ *
42
+ * @return true
43
+ */
44
+ public function canShowTab()
45
+ {
46
+ /* @var $model Mage_Cms_Model_Page */
47
+ $model = Mage::registry('cms_page');
48
+
49
+ if ($storeIds = $model->getStoreId()){
50
+
51
+ if (in_array(0, $storeIds)){
52
+ return true;
53
+ }
54
+
55
+ $defaultStoreId = Mage::helper('connector')->getDefaultStoreId();
56
+ if (!in_array($defaultStoreId, $model->getStoreId())){
57
+ return false;
58
+ }
59
+ }
60
+ return true;
61
+ }
62
+
63
+ /**
64
+ * Returns status flag about this tab hidden or not
65
+ *
66
+ * @return true
67
+ */
68
+ public function isHidden()
69
+ {
70
+ return false;
71
+ }
72
+
73
+ /**
74
+ * Check permission for passed action
75
+ *
76
+ * @param string $action
77
+ * @return bool
78
+ */
79
+ protected function _isAllowedAction($action)
80
+ {
81
+ return Mage::getSingleton('admin/session')->isAllowed('cms/page/' . $action);
82
+ }
83
+
84
+ /**
85
+ *
86
+ * @return int
87
+ */
88
+ public function getContentId() {
89
+ return Mage::app()->getRequest()->getParam('page_id');
90
+ }
91
+
92
+ /**
93
+ *
94
+ * @return int
95
+ */
96
+ public function getContentTypeId () {
97
+ return $this->_contentTypeId;
98
+ }
99
+
100
+ /**
101
+ *
102
+ * @return string
103
+ */
104
+ public function getTitle() {
105
+ return Mage::helper('connector')->__("Smartling Translation Actions");
106
+ }
107
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Fields.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Cms_Page_Fields
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_cms_page_fields";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('CMS Page Fields');
17
+
18
+ parent::__construct();
19
+ $this->_removeButton('add');
20
+ }
21
+
22
+ public function getCreateUrl()
23
+ {
24
+ return false;
25
+ }
26
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Cms/Page/Fields/Grid.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Cms_Page_Fields_Grid
10
+ extends Smartling_Connector_Block_Adminhtml_Cms_AbstractFlatGrid
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ $this->_typeName = 'cmsPage';
16
+
17
+ parent::__construct();
18
+ $this->setId('cmsPageGrid');
19
+ }
20
+
21
+ /**
22
+ * Prepare product attributes grid collection object
23
+ *
24
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
25
+ */
26
+ protected function _prepareCollection()
27
+ {
28
+
29
+ $collection = Mage::getResourceModel('connector/translate_fields_list_page_collection');
30
+
31
+ $this->setCollection($collection);
32
+
33
+ return parent::_prepareCollection();
34
+ }
35
+
36
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+ parent::__construct();
14
+ $this->_controller = "adminhtml_content";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('Contents list');
17
+ $this->_removeButton('add');
18
+ }
19
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Attribute.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Product
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Attribute
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ /**
13
+ * Defines default parameters
14
+ *
15
+ */
16
+ public function __construct() {
17
+ parent::__construct();
18
+ $this->_controller = "adminhtml_content_attribute";
19
+ $this->_blockGroup = "connector";
20
+
21
+ if ($this->getRequest()->getActionName() == 'confirm'){
22
+ $this->_headerText = Mage::helper('connector')->__('Confirm attributes items');
23
+
24
+ $this->_addButton('back', array(
25
+ 'label' => Mage::helper('adminhtml')->__('Back'),
26
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/view', array('_current'=>true)) . "')",
27
+ 'class' => 'back'
28
+ ));
29
+
30
+ $this->_addButton('save', array(
31
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
32
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save')."')",
33
+ 'class' => 'go'
34
+ ));
35
+
36
+ } else {
37
+
38
+ $this->_addButton('back', array(
39
+ 'label' => Mage::helper('adminhtml')->__('Back'),
40
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
41
+ 'class' => 'back'
42
+ ));
43
+
44
+ $this->_headerText = Mage::helper('connector')->__('Attributes content list');
45
+ }
46
+ $this->_removeButton('add');
47
+
48
+ }
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Attribute/Grid.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Attribute_Grid
9
+ extends Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
10
+ {
11
+
12
+ protected $_contentTypeId = 5;
13
+
14
+ protected $_contentType = Smartling_Connector_Model_Content_Attribute::CONTENT_TYPE;
15
+
16
+ /**
17
+ *
18
+ * @var string
19
+ */
20
+ protected $_controller;
21
+
22
+ /**
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_action;
27
+
28
+ /**
29
+ * Massaction block name
30
+ *
31
+ * @var string
32
+ */
33
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
34
+
35
+ public function __construct() {
36
+ parent::__construct();
37
+ $this->setId('productContent');
38
+ $this->setDefaultSort('entity_id');
39
+ $this->setDefaultDir('DESC');
40
+ $this->setUseAjax(false);
41
+ $this->setSaveParametersInSession(false);
42
+ $this->setVarNameFilter('content_filter');
43
+
44
+ $this->_controller = $this->getRequest()->getControllerName();
45
+ $this->_action = $this->getRequest()->getActionName();
46
+
47
+ //if confirm action - disable pagination and limits
48
+ if ($this->_action == 'confirm'){
49
+ $this->setPagerVisibility(false);
50
+ $this->setFilterVisibility(false);
51
+ }
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Product_Grid
57
+ */
58
+ protected function _prepareCollection() {
59
+
60
+
61
+ //for confirm action filter attributes by request
62
+ if ( $this->_action == 'confirm' ) {
63
+ $collection = Mage::getResourceModel('catalog/product_attribute_collection')
64
+ ->addVisibleFilter();
65
+ $contentIds = $this->getRequest()->getParam('content');
66
+ $collection->addAttributeToFilter('entity_id', array('in' => $contentIds));
67
+ $this->setCollection($collection);
68
+ } else {
69
+ parent::_prepareCollection();
70
+ }
71
+
72
+ Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
73
+
74
+ return $this;
75
+ }
76
+
77
+ /**
78
+ *
79
+ * @return string
80
+ */
81
+ public function getGridUrl()
82
+ {
83
+ return $this->getUrl('*/adminhtml_instance/view', array('_current'=>true));
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @param object $row
89
+ * @return string
90
+ */
91
+ public function getRowUrl($row)
92
+ {
93
+ return false;
94
+ }
95
+
96
+ /**
97
+ *
98
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
99
+ */
100
+ protected function _prepareMassaction() {
101
+ // in confirm action don't show massaction block
102
+ if ( $this->_controller == "adminhtml_instance" && $this->_action == 'confirm' ){
103
+ return;
104
+ }
105
+
106
+ $this->setMassactionIdField('entity_id');
107
+ $this->getMassactionBlock()->setFormFieldName('content');
108
+
109
+ $this->getMassactionBlock()->addItem('update', array(
110
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
111
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array( '_current' => true )),
112
+ 'selected' => 'selected',
113
+ ));
114
+
115
+ Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction();
116
+ return $this;
117
+ }
118
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Category.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Category
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Category
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+ parent::__construct();
14
+ $this->_controller = "adminhtml_content_category";
15
+ $this->_blockGroup = "connector";
16
+
17
+ if ($this->getRequest()->getActionName() == 'confirm'){
18
+ $this->_headerText = Mage::helper('connector')->__('Confirm category items');
19
+ $this->_addButton('save', array(
20
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
21
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save', array('_current' => true))."')",
22
+ 'class' => 'go'
23
+ ));
24
+ } else {
25
+
26
+ $this->_addButton('back', array(
27
+ 'label' => Mage::helper('adminhtml')->__('Back'),
28
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
29
+ 'class' => 'back'
30
+ ));
31
+
32
+ $this->_headerText = Mage::helper('connector')->__('Categories content list');
33
+ }
34
+ $this->_removeButton('add');
35
+
36
+
37
+ }
38
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Category/Grid.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Category_Grid
9
+ extends Mage_Adminhtml_Block_Widget_Grid
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var string
15
+ */
16
+ protected $_contentType = Smartling_Connector_Model_Content_Category::CONTENT_TYPE;
17
+
18
+ /**
19
+ *
20
+ * @var string
21
+ */
22
+ protected $_controller;
23
+
24
+ /**
25
+ *
26
+ * @var string
27
+ */
28
+ protected $_action;
29
+
30
+ /**
31
+ *
32
+ * @var int
33
+ */
34
+ protected $_contentTypeId = 4;
35
+
36
+ /**
37
+ * Massaction block name
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
42
+
43
+ public function __construct() {
44
+ parent::__construct();
45
+ $this->setId('categoryContent');
46
+ $this->setDefaultSort('entity_id');
47
+ $this->setDefaultDir('DESC');
48
+ $this->setUseAjax(true);
49
+ $this->setSaveParametersInSession(true);
50
+ $this->setVarNameFilter('content_filter');
51
+
52
+ $this->_controller = $this->getRequest()->getControllerName();
53
+ $this->_action = $this->getRequest()->getActionName();
54
+
55
+ //if confirm action - disable pagination and limits
56
+ if ($this->_action == 'confirm'){
57
+ $this->setPagerVisibility(false);
58
+ $this->setFilterVisibility(false);
59
+ }
60
+ }
61
+
62
+ /**
63
+ *
64
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Category_Grid
65
+ */
66
+ protected function _prepareCollection(){
67
+ $rootCategories = array(1);
68
+
69
+ $collection = Mage::getModel('catalog/category')->getCollection()
70
+ ->addAttributeToSelect('name');
71
+
72
+ if ($this->_action == 'confirm'){
73
+ $categoriesId = $this->getRequest()->getParam('content');
74
+ $collection->addAttributeToFilter('entity_id', array('in' => $categoriesId));
75
+ } else {
76
+ $collection->addAttributeToFilter('entity_id', array('nin' => $rootCategories))
77
+ ->addAttributeToSelect('title')
78
+ ->addAttributeToSelect('is_active')
79
+ ->addAttributeToSelect('include_in_menu')
80
+ ->addAttributeToSelect('display_mode')
81
+ ->setStoreId($this->getRequest()->getParam('store_group_id'));
82
+ }
83
+
84
+ $this->setCollection($collection);
85
+ return parent::_prepareCollection();
86
+ }
87
+
88
+ /**
89
+ * set grid columns
90
+ */
91
+ protected function _prepareColumns() {
92
+ // if in confirm action show other fields
93
+ if ( $this->_action == 'confirm' ){
94
+ $this->addColumn('entity_id', array(
95
+ 'header' => Mage::helper('connector')->__('Id'),
96
+ 'align' => 'left',
97
+ 'index' => 'entity_id',
98
+ 'width' => '10px',
99
+ 'filter' => false,
100
+ 'sortable' => false,
101
+ ));
102
+
103
+ $this->addColumn('name', array(
104
+ 'header' => Mage::helper('connector')->__('Category Name'),
105
+ 'align' => 'left',
106
+ 'index' => 'name',
107
+ 'filter' => false,
108
+ 'sortable' => false,
109
+ ));
110
+ } else {
111
+ $this->addColumn('entity_id', array(
112
+ 'header' => Mage::helper('connector')->__('Id'),
113
+ 'align' => 'left',
114
+ 'index' => 'entity_id',
115
+ 'width' => '10px'
116
+ ));
117
+
118
+ $this->addColumn('name', array(
119
+ 'header' => Mage::helper('connector')->__('Category Name'),
120
+ 'align' => 'left',
121
+ 'index' => 'name',
122
+ ));
123
+
124
+ $this->addColumn('display_mode', array(
125
+ 'header' => Mage::helper('connector')->__('Display Mode'),
126
+ 'align' => 'left',
127
+ 'index' => 'display_mode',
128
+ ));
129
+ }
130
+ parent::_prepareColumns();
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @return string
136
+ */
137
+ public function getGridUrl()
138
+ {
139
+ return parent::getGridUrl();
140
+ //return $this->getUrl('*/adminhtml_translator_category/grid', array('_current' => true));
141
+ }
142
+
143
+ /**
144
+ *
145
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
146
+ */
147
+ protected function _prepareMassaction() {
148
+ // in confirm action don't show massaction block
149
+ if ( $this->_action == 'confirm' ){
150
+ return;
151
+ }
152
+ $action = $this->getUrl('*/*/confirm', array('_current' => true));
153
+
154
+ $this->setMassactionIdField('entity_id');
155
+ $this->getMassactionBlock()->setFormFieldName('content');
156
+
157
+ $this->getMassactionBlock()->setAction($action);
158
+ $this->getMassactionBlock()->addItem('update', array(
159
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
160
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array('_current' => true)),
161
+ 'selected' => 'selected',
162
+ ));
163
+
164
+ //parent::_prepareMassaction();
165
+ return $this;
166
+ }
167
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsBlock.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsBlock
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_CmsBlock
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct(){
13
+ parent::__construct();
14
+ $this->_controller = "adminhtml_content_cmsBlock";
15
+ $this->_blockGroup = "connector";
16
+
17
+ if ($this->getRequest()->getActionName() == 'confirm'){
18
+ $this->_headerText = Mage::helper('connector')->__('Confirm static block items');
19
+ $this->_addButton('save', array(
20
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
21
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save')."')",
22
+ 'class' => 'go'
23
+ ));
24
+ } else {
25
+
26
+ $this->_addButton('back', array(
27
+ 'label' => Mage::helper('adminhtml')->__('Back'),
28
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
29
+ 'class' => 'back'
30
+ ));
31
+
32
+ $this->_headerText = Mage::helper('connector')->__('Static blocks content list');
33
+ }
34
+
35
+ $this->_removeButton('add');
36
+
37
+
38
+ }
39
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsBlock/Grid.php ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_CmsBlock_Grid
9
+ extends Mage_Adminhtml_Block_Cms_Block_Grid
10
+ {
11
+
12
+ protected $_contentType = Smartling_Connector_Model_Content_CmsBlock::CONTENT_TYPE;
13
+
14
+ /**
15
+ *
16
+ * @var string
17
+ */
18
+ protected $_controller;
19
+
20
+ /**
21
+ *
22
+ * @var string
23
+ */
24
+ protected $_action;
25
+
26
+ /**
27
+ *
28
+ * @var int
29
+ */
30
+ protected $_contentTypeId = 2;
31
+
32
+ /**
33
+ * Massaction block name
34
+ *
35
+ * @var string
36
+ */
37
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
38
+
39
+ public function __construct() {
40
+ parent::__construct();
41
+ $this->setId('cmsBlockContent');
42
+ $this->setDefaultSort('block_id');
43
+ $this->setDefaultDir('DESC');
44
+ $this->setUseAjax(true);
45
+ $this->setSaveParametersInSession(true);
46
+ $this->setVarNameFilter('content_filter');
47
+
48
+ $this->_controller = $this->getRequest()->getControllerName();
49
+ $this->_action = $this->getRequest()->getActionName();
50
+
51
+ //if confirm action - disable pagination and limits
52
+ if ($this->_action == 'confirm'){
53
+ $this->setPagerVisibility(false);
54
+ $this->setFilterVisibility(false);
55
+ }
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @return type
61
+ */
62
+ protected function _prepareColumns()
63
+ {
64
+ $baseUrl = $this->getUrl();
65
+
66
+ // if confirm action - shows only title and id button
67
+ if (($this->_controller == "adminhtml_instance") && ($this->_action == 'confirm')){
68
+
69
+ $this->addColumn('block_id', array(
70
+ 'header' => Mage::helper('cms')->__('Id'),
71
+ 'align' => 'left',
72
+ 'index' => 'block_id',
73
+ 'width' => '10px',
74
+ 'filter' => false,
75
+ 'sortable' => false,
76
+ ));
77
+
78
+ $this->addColumn('title', array(
79
+ 'header' => Mage::helper('cms')->__('Title'),
80
+ 'align' => 'left',
81
+ 'index' => 'title',
82
+ 'filter' => false,
83
+ 'sortable' => false,
84
+ ));
85
+
86
+ } else {
87
+ $this->addColumn('block_id', array(
88
+ 'header' => Mage::helper('cms')->__('Id'),
89
+ 'align' => 'left',
90
+ 'index' => 'block_id',
91
+ 'width' => '10px',
92
+ ));
93
+
94
+ $this->addColumn('title', array(
95
+ 'header' => Mage::helper('cms')->__('Title'),
96
+ 'align' => 'left',
97
+ 'index' => 'title',
98
+ ));
99
+
100
+ $this->addColumn('identifier', array(
101
+ 'header' => Mage::helper('cms')->__('Identifier'),
102
+ 'align' => 'left',
103
+ 'index' => 'identifier'
104
+ ));
105
+
106
+ if (!Mage::app()->isSingleStoreMode()) {
107
+ $this->addColumn('store_id', array(
108
+ 'header' => Mage::helper('cms')->__('Store View'),
109
+ 'index' => 'store_id',
110
+ 'type' => 'store',
111
+ 'store_all' => true,
112
+ 'store_view' => true,
113
+ 'sortable' => false,
114
+ 'filter_condition_callback'
115
+ => array($this, '_filterStoreCondition'),
116
+ ));
117
+ }
118
+
119
+ $this->addColumn('is_active', array(
120
+ 'header' => Mage::helper('cms')->__('Status'),
121
+ 'index' => 'is_active',
122
+ 'type' => 'options',
123
+ 'options' => array(
124
+ 0 => Mage::helper('cms')->__('Disabled'),
125
+ 1 => Mage::helper('cms')->__('Enabled')
126
+ ),
127
+ ));
128
+ }
129
+
130
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @return string
136
+ */
137
+ public function getGridUrl()
138
+ {
139
+ return $this->getUrl('*/adminhtml_translator_cmsBlock/grid', array('_current' => true));
140
+ }
141
+
142
+ /**
143
+ *
144
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
145
+ */
146
+ protected function _prepareMassaction() {
147
+ //if confirm action don't show massaction
148
+ if ($this->_controller == "adminhtml_instance" && $this->_action == 'confirm'){
149
+ return;
150
+ }
151
+
152
+ $this->setMassactionIdField('block_id');
153
+ $this->getMassactionBlock()->setFormFieldName('content');
154
+
155
+ $this->getMassactionBlock()->addItem('update', array(
156
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
157
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array('_current' => true)),
158
+ 'selected' => 'selected',
159
+ ));
160
+
161
+ Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction();
162
+ return $this;
163
+ }
164
+
165
+ /**
166
+ *
167
+ * @return \Mage_Adminhtml_Block_Cms_Block_Grid
168
+ */
169
+ protected function _prepareCollection() {
170
+
171
+ /* @var $collection Mage_Cms_Model_Mysql4_Block_Collection */
172
+ $collection = Mage::getModel('cms/block')->getCollection();
173
+
174
+ $resource = Mage::getSingleton('core/resource');
175
+ $storeGroupTableName = $resource->getTableName('core_store_group');
176
+ $smartlingProjectsLocales = $resource->getTableName('smartling_projects_locales');
177
+
178
+ $locales = $this->getRequest()->getParam('locales');
179
+
180
+ $stores_ids = array();
181
+
182
+ if(is_array($locales)) {
183
+ foreach($locales as $projects) {
184
+ foreach($projects as $store_id) {
185
+ $stores_ids[] = (int)$store_id;
186
+ }
187
+ }
188
+ }
189
+
190
+ $collection->getSelect()
191
+ ->joinInner(
192
+ array('cbs' => $resource->getTableName('cms_block_store')),
193
+ "cbs.block_id = main_table.block_id",
194
+ array('store_id'))
195
+ ->joinInner(
196
+ array('csg' => $storeGroupTableName),
197
+ "csg.default_store_id = cbs.store_id",
198
+ array())
199
+ ->joinLeft(
200
+ array('spl' => $smartlingProjectsLocales),
201
+ "csg.default_store_id = cbs.store_id",
202
+ array())
203
+ ->where('cbs.store_id = 0 or (cbs.store_id = spl.store_id and spl.store_id in (?))', array('in' => $stores_ids))
204
+ ->group('block_id');
205
+
206
+ if ($this->_controller == "adminhtml_instance" && $this->_action == 'confirm') { // only for confirmation action
207
+ $blocksIds = $this->getRequest()->getParam('content');
208
+ $collection->getSelect()
209
+ ->where('main_block.block_id in (?)', array('in' => $blocksIds));
210
+ }
211
+
212
+ $this->setCollection($collection);
213
+
214
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
215
+ }
216
+
217
+ /**
218
+ * Row click url
219
+ *
220
+ * @return string
221
+ */
222
+ public function getRowUrl($row)
223
+ {
224
+ return false;
225
+ }
226
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsPage.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsPage
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_CmsPage
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+ parent::__construct();
14
+ $this->_controller = "adminhtml_content_cmsPage";
15
+ $this->_blockGroup = "connector";
16
+
17
+ if ($this->getRequest()->getActionName() == 'confirm'){
18
+ $this->_headerText = Mage::helper('connector')->__('Confirm cms page items');
19
+ $this->_addButton('save', array(
20
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
21
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save')."')",
22
+ 'class' => 'go'
23
+ ));
24
+ } else {
25
+
26
+ $this->_addButton('back', array(
27
+ 'label' => Mage::helper('adminhtml')->__('Back'),
28
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
29
+ 'class' => 'back'
30
+ ));
31
+
32
+ $this->_headerText = Mage::helper('connector')->__('Cms pages content list');
33
+ }
34
+
35
+ $this->_removeButton('add');
36
+
37
+
38
+ }
39
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/CmsPage/Grid.php ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_CmsPage_Grid
9
+ extends Mage_Adminhtml_Block_Cms_Page_Grid
10
+ {
11
+
12
+ protected $_contentTypeId = 1;
13
+
14
+ /**
15
+ *
16
+ * @var string
17
+ */
18
+ protected $_contentType = Smartling_Connector_Model_Content_CmsPage::CONTENT_TYPE;
19
+
20
+ /**
21
+ *
22
+ * @var string
23
+ */
24
+ protected $_controller;
25
+
26
+ /**
27
+ *
28
+ * @var string
29
+ */
30
+ protected $_action;
31
+
32
+ /**
33
+ * Massaction block name
34
+ *
35
+ * @var string
36
+ */
37
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
38
+
39
+ public function __construct() {
40
+ parent::__construct();
41
+ $this->setId('cmsPageContent');
42
+ $this->setDefaultSort('page_id');
43
+ $this->setDefaultDir('DESC');
44
+ $this->setUseAjax(true);
45
+ $this->setSaveParametersInSession(true);
46
+ $this->setVarNameFilter('content_filter');
47
+
48
+ $this->_controller = $this->getRequest()->getControllerName();
49
+ $this->_action = $this->getRequest()->getActionName();
50
+
51
+ //if confirm action - disable pagination and limits
52
+ if ($this->_action == 'confirm'){
53
+ $this->setPagerVisibility(false);
54
+ $this->setFilterVisibility(false);
55
+ }
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @return type
61
+ */
62
+ protected function _prepareColumns() {
63
+ $baseUrl = $this->getUrl();
64
+
65
+ //if confirm action shows only two fields
66
+ if ( ($this->_controller == "adminhtml_instance") && ($this->_action == 'confirm') ){
67
+ $this->addColumn('page_id', array(
68
+ 'header' => Mage::helper('cms')->__('Id'),
69
+ 'align' => 'left',
70
+ 'index' => 'page_id',
71
+ 'width' => '25px',
72
+ 'filter' => false,
73
+ 'sortable' => false,
74
+ ));
75
+
76
+ $this->addColumn('title', array(
77
+ 'header' => Mage::helper('cms')->__('Title'),
78
+ 'align' => 'left',
79
+ 'index' => 'title',
80
+ 'filter' => false,
81
+ 'sortable' => false,
82
+ ));
83
+ } else {
84
+ $this->addColumn('page_id', array(
85
+ 'header' => Mage::helper('cms')->__('Id'),
86
+ 'align' => 'left',
87
+ 'index' => 'page_id',
88
+ 'width' => '25px'
89
+ ));
90
+
91
+ $this->addColumn('title', array(
92
+ 'header' => Mage::helper('cms')->__('Title'),
93
+ 'align' => 'left',
94
+ 'index' => 'title',
95
+ ));
96
+ $this->addColumn('identifier', array(
97
+ 'header' => Mage::helper('cms')->__('URL Key'),
98
+ 'align' => 'left',
99
+ 'index' => 'identifier'
100
+ ));
101
+
102
+ $this->addColumn('root_template', array(
103
+ 'header' => Mage::helper('cms')->__('Layout'),
104
+ 'index' => 'root_template',
105
+ 'type' => 'options',
106
+ 'options' => Mage::getSingleton('page/source_layout')->getOptions(),
107
+ ));
108
+
109
+ /**
110
+ * Check is single store mode
111
+ */
112
+ if (!Mage::app()->isSingleStoreMode()) {
113
+ $this->addColumn('store_id', array(
114
+ 'header' => Mage::helper('cms')->__('Store View'),
115
+ 'index' => 'store_id',
116
+ 'type' => 'store',
117
+ 'store_all' => true,
118
+ 'store_view' => true,
119
+ 'sortable' => false,
120
+ 'filter_condition_callback'
121
+ => array($this, '_filterStoreCondition'),
122
+ ));
123
+ }
124
+
125
+ $this->addColumn('is_active', array(
126
+ 'header' => Mage::helper('cms')->__('Status'),
127
+ 'index' => 'is_active',
128
+ 'type' => 'options',
129
+ 'options' => Mage::getSingleton('cms/page')->getAvailableStatuses()
130
+ ));
131
+ }
132
+
133
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
134
+ }
135
+
136
+ /**
137
+ *
138
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
139
+ */
140
+ protected function _prepareMassaction() {
141
+ //if confirm action don't show massaction
142
+ if ($this->_action == 'confirm'){
143
+ return;
144
+ }
145
+
146
+ $this->setMassactionIdField('page_id');
147
+ $this->getMassactionBlock()->setFormFieldName('content');
148
+
149
+ $this->getMassactionBlock()->addItem('update', array(
150
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
151
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array ('_current' => true) ),
152
+ 'selected' => 'selected',
153
+ ));
154
+
155
+ Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction();
156
+ return $this;
157
+ }
158
+
159
+ /**
160
+ *
161
+ * @return string
162
+ */
163
+ public function getGridUrl()
164
+ {
165
+ return $this->getUrl('*/adminhtml_translator_cmsPage/grid', array('_current' => true));
166
+ }
167
+
168
+ /**
169
+ *
170
+ * @return Mage_Adminhtml_Block_Widget_Grid
171
+ */
172
+ protected function _prepareCollection() {
173
+
174
+ /* @var $collection Mage_Cms_Model_Mysql4_Page_Collection */
175
+ $collection = Mage::getModel('cms/page')->getCollection();
176
+
177
+ $resource = Mage::getSingleton('core/resource');
178
+ $storeGroupTableName = $resource->getTableName('core_store_group');
179
+ $smartlingProjectsLocales = $resource->getTableName('smartling_projects_locales');
180
+
181
+ $locales = $this->getRequest()->getParam('locales');
182
+
183
+ $stores_ids = array();
184
+
185
+ if(is_array($locales)) {
186
+ foreach($locales as $projects) {
187
+ foreach($projects as $store_id) {
188
+ $stores_ids[] = (int)$store_id;
189
+ }
190
+ }
191
+ }
192
+
193
+ $collection->getSelect()
194
+ ->joinInner(
195
+ array('cps' => $resource->getTableName('cms_page_store')),
196
+ "cps.page_id = main_table.page_id",
197
+ array('store_id'))
198
+ ->joinInner(
199
+ array('csg' => $storeGroupTableName),
200
+ "csg.default_store_id = cps.store_id",
201
+ array())
202
+ ->joinLeft(
203
+ array('spl' => $smartlingProjectsLocales),
204
+ "csg.default_store_id = cps.store_id",
205
+ array())
206
+ ->where('cps.store_id = 0 or (cps.store_id = spl.store_id and spl.store_id in (?))', array('in' => $stores_ids))
207
+ ->group('page_id');
208
+
209
+ if ($this->_controller == "adminhtml_instance" && $this->_action == 'confirm') { // only for confirmation action
210
+ $pageIds = $this->getRequest()->getParam('content');
211
+ $collection->getSelect()
212
+ ->where('main_page.page_id in (?)', array('in' => $pageIds));
213
+ }
214
+
215
+ $this->setCollection($collection);
216
+
217
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
218
+ }
219
+
220
+ /**
221
+ * Row click url
222
+ *
223
+ * @return string
224
+ */
225
+ public function getRowUrl($row)
226
+ {
227
+ return parent::getGridUrl();
228
+ }
229
+
230
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Grid.php ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Grid
9
+ extends Mage_Adminhtml_Block_Widget_Grid
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int | null
15
+ */
16
+ protected $_contentTypeId = null;
17
+
18
+ /**
19
+ *
20
+ * @var string | null
21
+ */
22
+ protected $_contentType = null;
23
+
24
+ public function __construct() {
25
+ parent::__construct();
26
+ $this->setId('content');
27
+ $this->setDefaultSort('content_id');
28
+ $this->setDefaultDir('DESC');
29
+ $this->setUseAjax(true);
30
+ $this->setSaveParametersInSession(true);
31
+ $this->setVarNameFilter('content_filter');
32
+ if (!is_null($this->_contentType)){
33
+ $this->_contentTypeId = Mage::helper('connector')
34
+ ->findTypeIdByTypeName($this->_contentType);
35
+ }
36
+ }
37
+
38
+ /**
39
+ *
40
+ * prepare collection for grid
41
+ */
42
+ protected function _prepareCollection() {
43
+
44
+ $resource = Mage::getSingleton('core/resource');
45
+
46
+ $collection = Mage::getModel('connector/content')->getCollection();
47
+
48
+ if (!is_null($this->_contentTypeId) && $this->_contentTypeId !== 0){
49
+ $collection->addFieldToFilter('type', array('eq' => $this->_contentTypeId));
50
+ } else {
51
+ $collection->getSelect()->joinLeft(
52
+ array('content_types' => 'smartling_content_types'),
53
+ 'type = content_types.type_id',
54
+ array('type_name', 'type_id')
55
+ );
56
+ }
57
+ $collection->getSelect()->joinLeft(
58
+ array('user' => 'admin_user'),
59
+ 'submitter = user.user_id',
60
+ array('username')
61
+ );
62
+
63
+ $collection->getSelect()
64
+ ->joinInner(array('p' => $resource->getTableName('connector/projects')),
65
+ 'main_table.project_id = p.id',
66
+ array('project_name' => 'name')
67
+ )
68
+ ->joinInner(array('pl' => $resource->getTableName('connector/projects_locales')),
69
+ 'main_table.project_id = pl.parent_id and main_table.store_id = pl.store_id',
70
+ array('locale' => 'locale_code'))
71
+ ->order('main_table.origin_content_id')
72
+ ->order('main_table.status');
73
+
74
+ $this->setCollection($collection);
75
+ parent::_prepareCollection();
76
+ }
77
+
78
+ /**
79
+ *
80
+ * prepare columns
81
+ */
82
+ protected function _prepareColumns() {
83
+ $this->addColumn('content_title', array(
84
+ 'header' => Mage::helper('connector')->__('Content Title'),
85
+ 'align' => 'left',
86
+ 'index' => 'content_title',
87
+ 'renderer' => 'connector/adminhtml_grid_column_renderer_link',
88
+ ));
89
+
90
+ $this->addColumn('filename', array(
91
+ 'header' => Mage::helper('connector')->__('File Uri'),
92
+ 'align' => 'left',
93
+ 'index' => 'filename',
94
+ ));
95
+
96
+ if (is_null($this->_contentTypeId)){
97
+ $this->addColumn('type_name', array(
98
+ 'header' => Mage::helper('connector')->__('Content Type'),
99
+ 'align' => 'left',
100
+ 'index' => 'type_name',
101
+ 'filter' => 'adminhtml/widget_grid_column_filter_select',
102
+ 'options' => Mage::getModel('connector/source_content_types')->getOptions(),
103
+ ));
104
+ }
105
+
106
+ $this->addColumn('source_store_id', array(
107
+ 'header' => Mage::helper('connector')->__('Source Locale'),
108
+ 'align' => 'left',
109
+ 'index' => 'source_store_id',
110
+ 'type' => 'store',
111
+ 'store_all' => false,
112
+ 'store_view' => false,
113
+ 'filter' => false,
114
+ 'sortable' => true
115
+
116
+ ));
117
+
118
+ $this->addColumn('store_id', array(
119
+ 'header' => Mage::helper('connector')->__('Destination Locale'),
120
+ 'align' => 'left',
121
+ 'index' => 'store_id',
122
+ 'type' => 'store',
123
+ 'store_all' => false,
124
+ 'store_view' => false,
125
+ 'filter' => false,
126
+ 'sortable' => true
127
+
128
+ ));
129
+
130
+ $this->addColumn('username', array(
131
+ 'header' => Mage::helper('connector')->__('Submitter'),
132
+ 'align' => 'left',
133
+ 'index' => 'username',
134
+ 'width' => '100px'
135
+ ));
136
+
137
+ $this->addColumn('project_name', array(
138
+ 'header' => Mage::helper('connector')->__('Project Name'),
139
+ 'align' => 'left',
140
+ 'index' => 'project_name',
141
+ 'width' => '150px'
142
+ ));
143
+
144
+ $this->addColumn('submitted_time', array(
145
+ 'header' => Mage::helper('connector')->__('Submitted time'),
146
+ 'align' => 'left',
147
+ 'index' => 'submitted_time',
148
+ ));
149
+
150
+ $this->addColumn('percent', array(
151
+ 'header' => Mage::helper('connector')->__('Completed, %'),
152
+ 'align' => 'left',
153
+ 'index' => 'percent',
154
+ 'type' => 'text',
155
+ 'width' => '190px',
156
+ 'renderer' => 'connector/adminhtml_grid_column_renderer_progress',
157
+ ));
158
+
159
+ $this->addColumn('status', array(
160
+ 'header' => Mage::helper('connector')->__('Status'),
161
+ 'align' => 'left',
162
+ 'index' => 'status',
163
+ 'width' => '80px',
164
+ 'filter' => 'adminhtml/widget_grid_column_filter_select',
165
+ 'options' => Mage::getModel('connector/source_content_status')->getOptions(),
166
+ ));
167
+
168
+ $this->addColumn('action', array(
169
+ 'header' => Mage::helper('connector')->__('Action'),
170
+ 'width' => '80px',
171
+ 'filter' => false,
172
+ 'sortable' => false,
173
+ 'renderer' => 'connector/adminhtml_grid_column_renderer_download',
174
+ ));
175
+
176
+ Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
177
+ }
178
+
179
+ /**
180
+ *
181
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
182
+ */
183
+ protected function _prepareMassaction() {
184
+ $this->setMassactionIdField('content_id');
185
+ $this->getMassactionBlock()->setFormFieldName('content');
186
+
187
+ $this->getMassactionBlock()->addItem('update', array(
188
+ 'label' => Mage::helper('connector')->__('Update'),
189
+ 'url' => $this->getUrl('*/adminhtml_translator/update'),
190
+ ));
191
+
192
+ parent::_prepareMassaction();
193
+ return $this;
194
+
195
+ }
196
+
197
+ public function getGridUrl()
198
+ {
199
+ return $this->getUrl('*/*/grid', array('_current' => true));
200
+ }
201
+
202
+ /**
203
+ * Add custom filter by type_id from joined table
204
+ *
205
+ * @param string $column
206
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
207
+ */
208
+ public function _addColumnFilterToCollection($column) {
209
+ if ($column->getId() == 'type_name'){
210
+ if ($value = $column->getFilter()->getValue()){
211
+ $this->getCollection()->addFieldToFilter('type_id', array('eq' => $value));
212
+ }
213
+ } else {
214
+ parent::_addColumnFilterToCollection($column);
215
+ }
216
+ return $this;
217
+ }
218
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Grid/Column/Status.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Grid select input column renderer
4
+ *
5
+ * @author Smartling
6
+ */
7
+
8
+ class Smartling_Connector_Block_Adminhtml_Content_Grid_Column_Status
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Checkbox
10
+ {
11
+
12
+ /**
13
+ * Renders grid column
14
+ *
15
+ * @param Varien_Object $row
16
+ * @return string
17
+ */
18
+ public function renderOld(Varien_Object $row)
19
+ {
20
+ $name = $this->getColumn()->getName() ? $this->getColumn()->getName() : $this->getColumn()->getId();
21
+ $html = '<select name="' . $this->escapeHtml($name) . '" ' . $this->getColumn()->getValidateClass() . ' onchange="translateStatus(this, \'' . $row->getAttributeCode() . '\')">';
22
+ $value = $row->getData($this->getColumn()->getIndex());
23
+
24
+ foreach ($this->getColumn()->getOptions() as $val => $label){
25
+ $selected = ( ($val == $value && (!is_null($value))) ? ' selected="selected"' : '' );
26
+ $html .= '<option value="' . $this->escapeHtml($val) . '"' . $selected . '>';
27
+ $html .= $this->escapeHtml($label) . '</option>';
28
+ }
29
+ $html.='</select>';
30
+ return $html;
31
+ }
32
+
33
+ /**
34
+ * Renders grid column
35
+ *
36
+ * @param Varien_Object $row
37
+ * @return string
38
+ */
39
+ public function render(Varien_Object $row)
40
+ {
41
+ $values = $this->getColumn()->getValues();
42
+ $value = $row->getData('is_attached');
43
+ $checked = '';
44
+
45
+ if ($value == 1) {
46
+ $checked .= ' checked="checked"';
47
+ }
48
+
49
+ $disabledValues = $this->getColumn()->getDisabledValues();
50
+ if (is_array($disabledValues)) {
51
+ $disabled = in_array($value, $disabledValues) ? ' disabled="disabled"' : '';
52
+ }
53
+ else {
54
+ $disabled = ($value === $this->getColumn()->getDisabledValue()) ? ' disabled="disabled"' : '';
55
+ }
56
+
57
+ $this->setDisabled($disabled);
58
+
59
+ if ($this->getNoObjectId() || $this->getColumn()->getUseIndex()){
60
+ $v = $value;
61
+ } else {
62
+ $v = ($row->getId() != "") ? $row->getId():$value;
63
+ }
64
+
65
+ $checked .= ' onchange="translateStatus(this, \'' . $row->getAttributeCode() . '\')"';
66
+ return $this->_getCheckboxHtml($v, $checked);
67
+ }
68
+
69
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Localization.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsPage
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Localization
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+ parent::__construct();
14
+ $this->_controller = "adminhtml_content_localization";
15
+ $this->_blockGroup = "connector";
16
+
17
+ if ($this->getRequest()->getActionName() == 'confirm'){
18
+ $this->_headerText = Mage::helper('connector')->__('Confirm file list');
19
+ $this->_addButton('save', array(
20
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
21
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save')."')",
22
+ 'class' => 'go'
23
+ ));
24
+ } else {
25
+
26
+ $this->_addButton('back', array(
27
+ 'label' => Mage::helper('adminhtml')->__('Back'),
28
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
29
+ 'class' => 'back'
30
+ ));
31
+
32
+ $this->_headerText = Mage::helper('connector')->__('Localization files list');
33
+ }
34
+
35
+ $this->_removeButton('add');
36
+
37
+
38
+ }
39
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Localization/Grid.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Localization_Grid
9
+ extends Mage_Adminhtml_Block_Widget_Grid
10
+ {
11
+
12
+ protected $_contentTypeId = 6;
13
+
14
+ /**
15
+ *
16
+ * @var string
17
+ */
18
+ protected $_contentType = Smartling_Connector_Model_Content_Localization::CONTENT_TYPE;
19
+
20
+ /**
21
+ *
22
+ * @var string
23
+ */
24
+ protected $_controller;
25
+
26
+ /**
27
+ *
28
+ * @var string
29
+ */
30
+ protected $_action;
31
+
32
+ /**
33
+ * Massaction block name
34
+ *
35
+ * @var string
36
+ */
37
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
38
+
39
+ public function __construct() {
40
+ parent::__construct();
41
+ $this->setId('localizationContent');
42
+ $this->setDefaultSort('dir_name');
43
+ $this->setDefaultDir('ASC');
44
+ $this->setUseAjax(true);
45
+ $this->setSaveParametersInSession(true);
46
+ $this->setVarNameFilter('content_filter');
47
+
48
+ $this->_controller = $this->getRequest()->getControllerName();
49
+ $this->_action = $this->getRequest()->getActionName();
50
+
51
+ //if confirm action - disable pagination and limits
52
+ if ($this->_action == 'confirm'){
53
+ $this->setPagerVisibility(false);
54
+ $this->setFilterVisibility(false);
55
+ }
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @return type
61
+ */
62
+ protected function _prepareColumns() {
63
+ $baseUrl = $this->getUrl();
64
+
65
+ //if confirm action shows only two fields
66
+ if ( ($this->_controller == "adminhtml_instance") && ($this->_action == 'confirm') ){
67
+ $this->addColumn('id', array(
68
+ 'header' => Mage::helper('connector')->__('Id'),
69
+ 'align' => 'left',
70
+ 'index' => 'id',
71
+ 'width' => '25px',
72
+ 'filter' => false,
73
+ 'sortable' => false,
74
+ ));
75
+
76
+ $this->addColumn('file_path', array(
77
+ 'header' => Mage::helper('connector')->__('File path'),
78
+ 'align' => 'left',
79
+ 'index' => 'file_path',
80
+ 'filter' => false,
81
+ 'sortable' => false,
82
+ ));
83
+ } else {
84
+ $this->addColumn('id', array(
85
+ 'header' => Mage::helper('connector')->__('Id'),
86
+ 'align' => 'left',
87
+ 'index' => 'id',
88
+ 'width' => '25px'
89
+ ));
90
+
91
+ $this->addColumn('dir_name', array(
92
+ 'header' => Mage::helper('connector')->__('Localization dirrectory'),
93
+ 'align' => 'left',
94
+ 'index' => 'dir_name',
95
+ 'width' => '100px'
96
+ ));
97
+
98
+ $this->addColumn('file_path', array(
99
+ 'header' => Mage::helper('connector')->__('Path'),
100
+ 'align' => 'left',
101
+ 'index' => 'file_path',
102
+ ));
103
+ }
104
+
105
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
106
+ }
107
+
108
+ /**
109
+ *
110
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
111
+ */
112
+ protected function _prepareMassaction() {
113
+ //if confirm action don't show massaction
114
+ if ($this->_action == 'confirm'){
115
+ return;
116
+ }
117
+
118
+ $this->setMassactionIdField('id');
119
+ $this->getMassactionBlock()->setFormFieldName('content');
120
+
121
+ $this->getMassactionBlock()->addItem('update', array(
122
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
123
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array ('_current' => true) ),
124
+ 'selected' => 'selected',
125
+ ));
126
+
127
+ Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction();
128
+ return $this;
129
+ }
130
+
131
+ /**
132
+ *
133
+ * @return string
134
+ */
135
+ public function getGridUrl()
136
+ {
137
+ return $this->getUrl('*/adminhtml_translator_localization/grid', array('_current' => true));
138
+ }
139
+
140
+ /**
141
+ *
142
+ * @return Mage_Adminhtml_Block_Widget_Grid
143
+ */
144
+ protected function _prepareCollection() {
145
+
146
+ /* @var $collection Mage_Cms_Model_Mysql4_Page_Collection */
147
+ $collection = Mage::getModel('connector/localization_files_index')->getCollection();
148
+
149
+ $resource = Mage::getSingleton('core/resource');
150
+ $storeViewTableName = $resource->getTableName('core_store');
151
+ $storeGroupTableName = $resource->getTableName('core_store_group');
152
+
153
+ $locales = $this->getRequest()->getParam('locales');
154
+
155
+ $stores_ids = array();
156
+
157
+ if(is_array($locales)) {
158
+ foreach($locales as $projects) {
159
+ foreach($projects as $store_id) {
160
+ $stores_ids[] = (int)$store_id;
161
+ }
162
+ }
163
+ }
164
+
165
+
166
+ $collection->getSelect()
167
+ ->joinInner(array('cs' => $storeViewTableName),
168
+ 'cs.store_localization_dir = main_table.dir_name',
169
+ array())
170
+ ->joinInner(array('csg' => $storeGroupTableName),
171
+ 'cs.group_id = csg.default_store_id',
172
+ array())
173
+ ->joinInner(array('cs2' => $storeViewTableName),
174
+ 'csg.group_id = cs2.group_id',
175
+ array())
176
+ ->where('cs2.store_id in (?)', array('in' => $stores_ids))
177
+ ->group('main_table.id');
178
+
179
+ if ($this->_controller == "adminhtml_instance" && $this->_action == 'confirm') { // only for confirmation action
180
+ $pageIds = $this->getRequest()->getParam('content');
181
+ $collection->getSelect()
182
+ ->where('main_page.id in (?)', array('in' => $pageIds));
183
+ }
184
+
185
+ $this->setCollection($collection);
186
+
187
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
188
+ }
189
+
190
+ /**
191
+ * Row click url
192
+ *
193
+ * @return string
194
+ */
195
+ public function getRowUrl($row)
196
+ {
197
+ return false;
198
+ }
199
+
200
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Product.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Product
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Product
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ /**
13
+ * Defines default parameters
14
+ *
15
+ */
16
+ public function __construct() {
17
+ parent::__construct();
18
+ $this->_controller = "adminhtml_content_product";
19
+ $this->_blockGroup = "connector";
20
+
21
+ if ($this->getRequest()->getActionName() == 'confirm'){
22
+ $this->_headerText = Mage::helper('connector')->__('Confirm product items');
23
+
24
+ $this->_addButton('back', array(
25
+ 'label' => Mage::helper('adminhtml')->__('Back'),
26
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/view', array('_current'=>true)) . "')",
27
+ 'class' => 'back'
28
+ ));
29
+
30
+ $this->_addButton('save', array(
31
+ 'label' => Mage::helper('adminhtml')->__('Add to translation queue'),
32
+ 'onclick' => "setLocation('".$this->getUrl('*/*/save')."')",
33
+ 'class' => 'go'
34
+ ));
35
+
36
+ } else {
37
+
38
+ $this->_addButton('back', array(
39
+ 'label' => Mage::helper('adminhtml')->__('Back'),
40
+ 'onclick' => "setLocation('" . $this->getUrl('*/*/edit') . "')",
41
+ 'class' => 'back'
42
+ ));
43
+
44
+ $this->_headerText = Mage::helper('connector')->__('Products content list');
45
+ }
46
+ $this->_removeButton('add');
47
+
48
+ }
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Content/Product/Grid.php ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Grid
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Content_Product_Grid
9
+ extends Mage_Adminhtml_Block_Catalog_Product_Grid
10
+ {
11
+
12
+ protected $_contentTypeId = 3;
13
+
14
+ protected $_contentType = Smartling_Connector_Model_Content_Product::CONTENT_TYPE;
15
+
16
+ /**
17
+ *
18
+ * @var string
19
+ */
20
+ protected $_controller;
21
+
22
+ /**
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_action;
27
+
28
+ /**
29
+ * Massaction block name
30
+ *
31
+ * @var string
32
+ */
33
+ protected $_massactionBlockName = 'connector/adminhtml_grid_massaction';
34
+
35
+ public function __construct() {
36
+ parent::__construct();
37
+ $this->setId('productContent');
38
+ $this->setDefaultSort('entity_id');
39
+ $this->setDefaultDir('DESC');
40
+ $this->setUseAjax(false);
41
+ $this->setSaveParametersInSession(false);
42
+ $this->setVarNameFilter('content_filter');
43
+
44
+ $this->_controller = $this->getRequest()->getControllerName();
45
+ $this->_action = $this->getRequest()->getActionName();
46
+
47
+ //if confirm action - disable pagination and limits
48
+ if ($this->_action == 'confirm'){
49
+ $this->setPagerVisibility(false);
50
+ $this->setFilterVisibility(false);
51
+ }
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Product_Grid
57
+ */
58
+ protected function _prepareCollection() {
59
+ $store = $this->_getStore();
60
+ $collection = Mage::getModel('catalog/product')->getCollection()
61
+ ->addAttributeToSelect('sku')
62
+ ->addAttributeToSelect('name')
63
+ ->addAttributeToSelect('type_id');
64
+
65
+ //for confirm action filter products by request
66
+ if ( $this->_action == 'confirm' ){
67
+ $productIds = $this->getRequest()->getParam('content');
68
+ $collection->addAttributeToFilter('entity_id', array('in' => $productIds));
69
+ } else {
70
+
71
+ $website_id = $this->getRequest()->getParam('website_id');
72
+ $collection->addWebsiteFilter($website_id);
73
+
74
+ if ($store->getId()) {
75
+ //$collection->setStoreId($store->getId());
76
+ $adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
77
+
78
+ $collection->addStoreFilter($store);
79
+ $collection->joinAttribute(
80
+ 'name',
81
+ 'catalog_product/name',
82
+ 'entity_id',
83
+ null,
84
+ 'inner',
85
+ $adminStore
86
+ );
87
+ $collection->joinAttribute(
88
+ 'custom_name',
89
+ 'catalog_product/name',
90
+ 'entity_id',
91
+ null,
92
+ 'inner',
93
+ $store->getId()
94
+ );
95
+ $collection->joinAttribute(
96
+ 'status',
97
+ 'catalog_product/status',
98
+ 'entity_id',
99
+ null,
100
+ 'inner',
101
+ $store->getId()
102
+ );
103
+ $collection->joinAttribute(
104
+ 'visibility',
105
+ 'catalog_product/visibility',
106
+ 'entity_id',
107
+ null,
108
+ 'inner',
109
+ $store->getId()
110
+ );
111
+ }
112
+ else {
113
+ $collection->addAttributeToSelect('price');
114
+ $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
115
+ $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
116
+ }
117
+ }
118
+
119
+ $this->setCollection($collection);
120
+
121
+ Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
122
+ $this->getCollection()->addWebsiteNamesToResult();
123
+
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ *
129
+ * @return \Mage_Adminhtml_Block_Widget_Grid
130
+ */
131
+ protected function _prepareColumns(){
132
+ // if not confirm action show other fields
133
+ if (($this->_controller == "adminhtml_instance") && ($this->_action == 'confirm') ){
134
+ $this->addColumn('entity_id',
135
+ array(
136
+ 'header' => Mage::helper('catalog')->__('ID'),
137
+ 'width' => '50px',
138
+ 'type' => 'number',
139
+ 'index' => 'entity_id',
140
+ 'filter' => false,
141
+ 'sortable' => false,
142
+ ));
143
+ $this->addColumn('name',
144
+ array(
145
+ 'header'=> Mage::helper('catalog')->__('Name'),
146
+ 'index' => 'name',
147
+ 'filter' => false,
148
+ 'sortable' => false,
149
+ ));
150
+ } else {
151
+ $this->addColumn('entity_id',
152
+ array(
153
+ 'header'=> Mage::helper('catalog')->__('ID'),
154
+ 'width' => '50px',
155
+ 'type' => 'number',
156
+ 'index' => 'entity_id',
157
+ ));
158
+ $this->addColumn('name',
159
+ array(
160
+ 'header'=> Mage::helper('catalog')->__('Name'),
161
+ 'index' => 'name',
162
+ ));
163
+
164
+ $store = $this->_getStore();
165
+ if ($store->getId()) {
166
+ $this->addColumn('custom_name',
167
+ array(
168
+ 'header'=> Mage::helper('catalog')->__('Name in %s', $store->getName()),
169
+ 'index' => 'custom_name',
170
+ ));
171
+ }
172
+
173
+ $this->addColumn('type',
174
+ array(
175
+ 'header'=> Mage::helper('catalog')->__('Type'),
176
+ 'width' => '60px',
177
+ 'index' => 'type_id',
178
+ 'type' => 'options',
179
+ 'options' => Mage::getSingleton('catalog/product_type')->getOptionArray(),
180
+ ));
181
+
182
+ $this->addColumn('sku',
183
+ array(
184
+ 'header'=> Mage::helper('catalog')->__('SKU'),
185
+ 'width' => '80px',
186
+ 'index' => 'sku',
187
+ ));
188
+
189
+ $store = $this->_getStore();
190
+
191
+ $this->addColumn('visibility',
192
+ array(
193
+ 'header'=> Mage::helper('catalog')->__('Visibility'),
194
+ 'width' => '70px',
195
+ 'index' => 'visibility',
196
+ 'type' => 'options',
197
+ 'options' => Mage::getModel('catalog/product_visibility')->getOptionArray(),
198
+ ));
199
+
200
+ $this->addColumn('status',
201
+ array(
202
+ 'header'=> Mage::helper('catalog')->__('Status'),
203
+ 'width' => '70px',
204
+ 'index' => 'status',
205
+ 'type' => 'options',
206
+ 'options' => Mage::getSingleton('catalog/product_status')->getOptionArray(),
207
+ ));
208
+
209
+ if (!Mage::app()->isSingleStoreMode()) {
210
+ $this->addColumn('websites',
211
+ array(
212
+ 'header'=> Mage::helper('catalog')->__('Websites'),
213
+ 'width' => '100px',
214
+ 'sortable' => false,
215
+ 'index' => 'websites',
216
+ 'type' => 'options',
217
+ 'options' => Mage::getModel('core/website')->getCollection()->toOptionHash(),
218
+ ));
219
+ }
220
+ }
221
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
222
+ }
223
+
224
+ /**
225
+ *
226
+ * @param Mage_Adminhtml_Block_Widget_Grid_Column $column
227
+ * @return string
228
+ */
229
+ protected function _addColumnFilterToCollection($column)
230
+ {
231
+ if ($this->getCollection()) {
232
+ if ($column->getId() == 'websites') {
233
+ $this->getCollection()->joinField('websites',
234
+ 'catalog/product_website',
235
+ 'website_id',
236
+ 'product_id=entity_id',
237
+ null,
238
+ 'left');
239
+ }
240
+ }
241
+ return Mage_Adminhtml_Block_Widget_Grid::_addColumnFilterToCollection($column);
242
+ }
243
+
244
+ /**
245
+ *
246
+ * @return string
247
+ */
248
+ public function getGridUrl()
249
+ {
250
+ return $this->getUrl('*/adminhtml_instance/view', array('_current'=>true));
251
+ }
252
+
253
+ /**
254
+ *
255
+ * @param object $row
256
+ * @return string
257
+ */
258
+ public function getRowUrl($row)
259
+ {
260
+ return $this->getUrl('adminhtml/catalog_product/edit', array(
261
+ 'store'=>$this->getRequest()->getParam('store'),
262
+ 'id'=>$row->getId())
263
+ );
264
+ }
265
+
266
+ /**
267
+ *
268
+ * @return \Smartling_Connector_Block_Adminhtml_Content_Grid
269
+ */
270
+ protected function _prepareMassaction() {
271
+ // in confirm action don't show massaction block
272
+ if ( $this->_controller == "adminhtml_instance" && $this->_action == 'confirm' ){
273
+ return;
274
+ }
275
+
276
+ $this->setMassactionIdField('entity_id');
277
+ $this->getMassactionBlock()->setFormFieldName('content');
278
+
279
+ $this->getMassactionBlock()->addItem('update', array(
280
+ 'label' => Mage::helper('connector')->__('Add To Smartling Translations'),
281
+ 'url' => $this->getUrl('*/adminhtml_instance/confirm', array( '_current' => true )),
282
+ 'selected' => 'selected',
283
+ ));
284
+
285
+ Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction();
286
+ return $this;
287
+ }
288
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Edit/Tab/Translations.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Tranlsations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Edit_Tab_Translations
9
+ extends Mage_Adminhtml_Block_Widget_Form
10
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
11
+ {
12
+
13
+ /**
14
+ *
15
+ * @var int
16
+ */
17
+ protected $_contentTypeId;
18
+
19
+ public function __construct() {
20
+ parent::__construct();
21
+ $this->setTemplate('connector/adminhtml/edit/tab/translations.phtml');
22
+ }
23
+
24
+ /**
25
+ * Prepare label for tab
26
+ *
27
+ * @return string
28
+ */
29
+ public function getTabLabel()
30
+ {
31
+ return Mage::helper('connector')->__('Smartling Translations');
32
+ }
33
+
34
+ /**
35
+ * Prepare title for tab
36
+ *
37
+ * @return string
38
+ */
39
+ public function getTabTitle()
40
+ {
41
+ return Mage::helper('connector')->__('Smartling Translations');
42
+ }
43
+
44
+ /**
45
+ * Returns status flag about this tab can be shown or not
46
+ *
47
+ * @return true
48
+ */
49
+ public function canShowTab()
50
+ {
51
+ /* @var $model Mage_Cms_Model_Page */
52
+ $model = Mage::registry('cms_block');
53
+
54
+ if ($storeIds = $model->getStoreId()){
55
+
56
+ if (in_array(0, $storeIds)){
57
+ return true;
58
+ }
59
+
60
+ $defaultStoreId = Mage::helper('connector')->getDefaultStoreId();
61
+ if (!in_array($defaultStoreId, $model->getStoreId())){
62
+ return false;
63
+ }
64
+ }
65
+ return true;
66
+ }
67
+
68
+ /**
69
+ * Returns status flag about this tab hidden or not
70
+ *
71
+ * @return true
72
+ */
73
+ public function isHidden()
74
+ {
75
+ return false;
76
+ }
77
+
78
+ /**
79
+ * Check permission for passed action
80
+ *
81
+ * @param string $action
82
+ * @return bool
83
+ */
84
+ protected function _isAllowedAction($action)
85
+ {
86
+ return Mage::getSingleton('admin/session')->isAllowed('cms/page/' . $action);
87
+ }
88
+
89
+ /**
90
+ *
91
+ * @return boolean | Samrtling_Connector_Model_Resource_Content_Collection
92
+ */
93
+ public function getContentItems() {
94
+ $id = $this->getContentId();
95
+ if (!$id) {
96
+ return false;
97
+ }
98
+ $collection = Mage::getModel('connector/content')->getCollection()
99
+ ->addFieldToFilter('type', array('eq' => $this->_contentTypeId))
100
+ ->addFieldToFilter('origin_content_id', array('eq' => (int) $id));
101
+ return $collection;
102
+ }
103
+
104
+ /**
105
+ *
106
+ * @return int
107
+ */
108
+ public function getContentId() {
109
+ return Mage::app()->getRequest()->getParam('page_id');
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @param int $contentTypeId
115
+ * @param int $content_id
116
+ * @return array
117
+ */
118
+ public function findAvailableLocales($contentTypeId = '', $content_id = '', $website_ids = array()) {
119
+ return Mage::getModel('connector/projects')->getProjectsLocales($contentTypeId, $content_id, $website_ids);
120
+ }
121
+
122
+ /**
123
+ *
124
+ * @return int
125
+ */
126
+ public function getContentTypeId() {
127
+ return $this->_contentTypeId;
128
+ }
129
+
130
+ /**
131
+ *
132
+ * @return string
133
+ */
134
+ public function getTitle() {
135
+ return Mage::helper('connector')->__("Smartling Translation Actions");
136
+ }
137
+
138
+ /**
139
+ *
140
+ * @param int | float $percent
141
+ * @return string
142
+ */
143
+ public function getStatusImageUrl ($percent, $includePath = false) {
144
+ $imgSrc = '';
145
+ if (floatval ($percent) == 0.00) {
146
+ $imgSrc = 'wait.png';
147
+ } elseif (floatval($percent) > 0 && floatval($percent) < 100) {
148
+ $imgSrc = 'inprogress.png';
149
+ } elseif (floatval($percent) == 100.00) {
150
+ $imgSrc = 'translated.png';
151
+ }
152
+
153
+ if($includePath) {
154
+ $themeParams = array('_area' => 'adminhtml','_theme' => 'default');
155
+ $imgSrc = Mage::getDesign()->getSkinBaseUrl($themeParams) . 'smartling' . DS . 'images' . DS . $imgSrc;
156
+ }
157
+
158
+ return $imgSrc;
159
+ }
160
+
161
+ /**
162
+ *
163
+ * @param string $id
164
+ * @param string $label
165
+ * @return string
166
+ */
167
+ public function getButtonHtmlContent($id, $label) {
168
+ $button = Mage::app()->getLayout()->createBlock('adminhtml/widget_button');
169
+ $button->setId($id)
170
+ ->setLabel($label);
171
+ return $button->toHtml();
172
+ }
173
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Download.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Progress
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Grid_Column_Renderer_Download
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
10
+ {
11
+ public function render(Varien_Object $row){
12
+
13
+ $data = $row->getData();
14
+
15
+ if($data['percent'] == 100 || $data['status'] == Smartling_Connector_Model_Content::CONTENT_STATUS_NEW) {
16
+ return '';
17
+ }
18
+
19
+ $params = array(
20
+ 'content_id' => $data['content_id'],
21
+ 'store' => $this->getRequest()->getParam('store')
22
+ );
23
+
24
+ $url = Mage::helper("adminhtml")->getUrl("*/adminhtml_translator/download", $params);
25
+
26
+ $html = '<a href="' . $url . '" class="download">'
27
+ . Mage::helper('connector')->__('Download')
28
+ . "</a>";
29
+
30
+ return $html;
31
+ }
32
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Link.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Description of Progress
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Block_Adminhtml_Grid_Column_Renderer_Link
8
+ extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ public function render(Varien_Object $row)
11
+ {
12
+
13
+ $data = $row->getData();
14
+ $contentModel = Mage::getModel('connector/content_' . $data['type_name']);
15
+
16
+ /**
17
+ * @TODO modify for all types usage
18
+ */
19
+ if( ($contentModel->getContentTypeEntityModel() instanceof Mage_Catalog_Model_Product) == false ) {
20
+ return $data['content_title'];
21
+ }
22
+
23
+ $url = Mage::helper("adminhtml")->getUrl("adminhtml/catalog_product/edit", array('id' => $data['origin_content_id']));
24
+
25
+ $value = $row->getData($this->getColumn()->getIndex());
26
+
27
+ $html = '<a href="' . $url . '" target="_blank">'
28
+ . $data['content_title']
29
+ . "</a>";
30
+
31
+ return $html;
32
+ }
33
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Column/Renderer/Progress.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Progress
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Grid_Column_Renderer_Progress
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
10
+ {
11
+ public function render(Varien_Object $row){
12
+
13
+ $data = $row->getData();
14
+
15
+ $percent = $data[$this->getColumn()->getIndex()];
16
+
17
+ $elementWraperId = 'status_wraper_' . $row->getContentId();
18
+ $elementProgressId = $this->getColumn()->getId() . '_' . $row->getContentId();
19
+ $elementProgressIdContent = $this->getColumn()->getId() . '_content_' . $row->getContentId();
20
+
21
+ $loading_style = '';
22
+ $display = '';
23
+
24
+ if($percent < 100 && $data['status'] != Smartling_Connector_Model_Content::CONTENT_STATUS_NEW) {
25
+ $loading_style = ' bar-loading';
26
+ } else {
27
+ $display = 'display:block;';
28
+ }
29
+
30
+ $html = "<div id='" . $elementWraperId . "' class='bar-default-wraper{$loading_style}'>"
31
+ . "<div id='" . $elementProgressId . "' class='bar-status' style='width:{$percent}%;{$display}' ></div>"
32
+ . "</div>"
33
+ . "<div id='" . $elementProgressIdContent . "' class='cell-percent'>" . $percent . "%</div>";
34
+
35
+ return $html;
36
+ }
37
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Grid/Massaction.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Massaction
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Grid_Massaction
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Massaction_Abstract
10
+ {
11
+ protected $_action = '';
12
+
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ $this->setTemplate('connector/adminhtml/widget/grid/massaction.phtml');
17
+ $this->setErrorText(Mage::helper('catalog')->jsQuoteEscape(Mage::helper('catalog')->__('Please select items.')));
18
+ }
19
+
20
+ /**
21
+ * Retrieve apply button html
22
+ *
23
+ * @return string
24
+ */
25
+ public function getApplyButtonHtml()
26
+ {
27
+ return $this->getButtonHtml($this->__('Continue'), $this->getJsObjectName() . ".apply()");
28
+ }
29
+
30
+ /**
31
+ *
32
+ * @return string
33
+ */
34
+ public function getAction() {
35
+ return $this->_action;
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param string $url
41
+ * @return string
42
+ */
43
+ public function setAction($url) {
44
+ $this->_action = $url;
45
+ return $this->_action;
46
+ }
47
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Edit.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Description of Edit
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Block_Adminhtml_Instance_Edit
8
+ extends Mage_Adminhtml_Block_Widget_Form_Container
9
+ {
10
+
11
+ /**
12
+ * Internal constructor
13
+ *
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->_objectId = 'instance_id';
19
+ $this->_blockGroup = 'connector';
20
+ $this->_controller = 'adminhtml_instance';
21
+ $headerText = "Smartling Bulk Submits";
22
+ $this->_headerText = Mage::helper('connector')->__($headerText);
23
+ $this->_removeButton('save');
24
+ $this->_removeButton('back');
25
+ $this->_removeButton('reset');
26
+ }
27
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Edit/Form.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Settings
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Instance_Edit_Form
9
+ extends Mage_Adminhtml_Block_Widget_Form
10
+ {
11
+
12
+ protected function _construct()
13
+ {
14
+ parent::_construct();
15
+ $this->setActive(true);
16
+ }
17
+
18
+ /**
19
+ * Prepare form before rendering HTML
20
+ *
21
+ * @return Mage_Widget_Block_Adminhtml_Widget_Instance_Edit_Tab_Settings
22
+ */
23
+ protected function _prepareForm()
24
+ {
25
+ $form = new Varien_Data_Form(array(
26
+ 'id' => 'edit_form',
27
+ 'action' => $this->getUrl('*/*/view'),
28
+ 'method' => 'post'
29
+ ));
30
+ $form->setUseContainer(false);
31
+ $this->setForm($form);
32
+ return parent::_prepareForm();
33
+ }
34
+
35
+ public function getFormHtml()
36
+ {
37
+ return '<div id="edit_form_container"></div>';
38
+ }
39
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Attribute.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_Attribute
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_attribute';
10
+ $this->_formType = 'attribute';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName,
20
+ 'name' => $this->_formName
21
+ ));
22
+ $form->setUseContainer(true);
23
+ $this->setForm($form);
24
+ $entity_type = 'attribute';
25
+
26
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
27
+
28
+ $fieldsetProfile->addType('profiles','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
29
+
30
+ $fieldsetProfile->addField('locales', 'profiles', array(
31
+ 'name' => 'locales[]',
32
+ 'layout' => $this->getLayout(),
33
+ 'required' => false,
34
+ 'class' => 'sl-required-entry-multy',
35
+ 'entity_type' => $entity_type
36
+ ))
37
+ ->setFilterWebsiteId(-1)
38
+ ->setFilterId(-1)
39
+ ->setEntityType($entity_type);
40
+
41
+ $fieldsetProfile->addField('content_type', 'hidden', array(
42
+ 'name' => 'content_type',
43
+ 'value' => $this->getContentTypeId()
44
+ ));
45
+
46
+ return parent::_prepareForm();
47
+ }
48
+
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Category.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_Category
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_category';
10
+ $this->_formType = 'category';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName
20
+ ));
21
+ $form->setUseContainer(true);
22
+ $this->setForm($form);
23
+
24
+ $fieldset = $form->addFieldset('website', array('legend' => $this->__('Website')));
25
+
26
+ $this->_addElementTypes($fieldset);
27
+
28
+ $fieldset->addField('store_group_id', 'select', array(
29
+ 'name' => 'store_group_id',
30
+ 'title' => $this->__('Store'),
31
+ 'label' => $this->__('Store'),
32
+ 'required' => true,
33
+ 'onchange' => 'getProfilesFor' . ucfirst($this->_formType) . '(this)',
34
+ 'values' => Mage::getModel('connector/source_stores')->toOptionArray(true),
35
+ ));
36
+
37
+ $fieldset->addField('content_type', 'hidden', array(
38
+ 'name' => 'content_type',
39
+ 'value' => $this->getContentTypeId()
40
+ ));
41
+
42
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
43
+
44
+ $fieldsetProfile->addType('profiles', 'Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
45
+
46
+ $fieldsetProfile->addField('stores', 'profiles', array(
47
+ 'name' => 'stores[]',
48
+ 'layout' => $this->getLayout(),
49
+ 'required' => false,
50
+ 'class' => 'sl-required-entry-multy',
51
+ 'entity_type' => 'category'
52
+ ));
53
+
54
+ return parent::_prepareForm();
55
+ }
56
+
57
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/CmsBlock.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_CmsBlock
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_cmsblock';
10
+ $this->_formType = 'cmsblock';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName,
20
+ 'name' => $this->_formName
21
+ ));
22
+ $form->setUseContainer(true);
23
+ $this->setForm($form);
24
+ $entity_type = 'cmsBlock';
25
+
26
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
27
+
28
+ $fieldsetProfile->addType('profiles','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
29
+
30
+ $fieldsetProfile->addField('stores', 'profiles', array(
31
+ 'name' => 'stores[]',
32
+ 'layout' => $this->getLayout(),
33
+ 'required' => false,
34
+ 'class' => 'sl-required-entry-multy',
35
+ 'entity_type' => $entity_type
36
+ ))
37
+ ->setFilterWebsiteId(-1)
38
+ ->setFilterId(-1)
39
+ ->setEntityType($entity_type);
40
+
41
+ $fieldsetProfile->addField('content_type', 'hidden', array(
42
+ 'name' => 'content_type',
43
+ 'value' => $this->getContentTypeId()
44
+ ));
45
+
46
+ return parent::_prepareForm();
47
+ }
48
+
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/CmsPage.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_cmsPage
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_cmspage';
10
+ $this->_formType = 'cmspage';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName,
20
+ 'name' => $this->_formName
21
+ ));
22
+ $form->setUseContainer(true);
23
+ $this->setForm($form);
24
+ $entity_type = 'cmsPage';
25
+
26
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
27
+
28
+ $fieldsetProfile->addType('profiles','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
29
+
30
+ $fieldsetProfile->addField('locales', 'profiles', array(
31
+ 'name' => 'locales[]',
32
+ 'layout' => $this->getLayout(),
33
+ 'required' => false,
34
+ 'class' => 'sl-required-entry-multy',
35
+ 'entity_type' => $entity_type
36
+ ))
37
+ ->setFilterWebsiteId(-1)
38
+ ->setFilterId(-1)
39
+ ->setEntityType($entity_type);
40
+
41
+ $fieldsetProfile->addField('content_type', 'hidden', array(
42
+ 'name' => 'content_type',
43
+ 'value' => $this->getContentTypeId()
44
+ ));
45
+
46
+ return parent::_prepareForm();
47
+ }
48
+
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Default.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_Default
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+ protected function _prepareLayout()
7
+ {
8
+ $this->setChild('continue_button',
9
+ $this->getLayout()->createBlock('adminhtml/widget_button')
10
+ ->setData(array(
11
+ 'label' => Mage::helper('catalog')->__('Continue'),
12
+ 'onclick' => "this.form.submit()",
13
+ 'class' => 'save'
14
+ ))
15
+ );
16
+ return parent::_prepareLayout();
17
+ }
18
+
19
+ protected function _prepareForm()
20
+ {
21
+
22
+ $form = new Varien_Data_Form(array(
23
+ 'action' => $this->getUrl('*/*/view'),
24
+ 'method' => 'post',
25
+ 'id' => 'website_form_default'
26
+ ));
27
+ $form->setUseContainer(true);
28
+ $this->setForm($form);
29
+
30
+ $fieldset = $form->addFieldset('website', array('legend' => $this->__('Profiles')));
31
+
32
+ $this->_addElementTypes($fieldset);
33
+
34
+ $fieldset->addField('store_ids', 'multiselect', array(
35
+ 'name' => 'store_ids[]',
36
+ 'label' => Mage::helper('connector')->__('Locales'),
37
+ 'title' => Mage::helper('connector')->__('Locales'),
38
+ 'required' => true,
39
+ 'values' => Mage::getSingleton('connector/source_projects')->toOptionArray()
40
+ ));
41
+
42
+
43
+ $fieldset->addField('continue_button', 'note', array(
44
+ 'text' => $this->getChildHtml('continue_button'),
45
+ ));
46
+
47
+ return parent::_prepareForm();
48
+ }
49
+
50
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Localization.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_Localization
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_localization';
10
+ $this->_formType = 'localization';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName,
20
+ 'name' => $this->_formName
21
+ ));
22
+ $form->setUseContainer(true);
23
+ $this->setForm($form);
24
+ $entity_type = 'localization';
25
+
26
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
27
+
28
+ $fieldsetProfile->addType('profiles','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
29
+
30
+ $fieldsetProfile->addField('locales', 'profiles', array(
31
+ 'name' => 'locales[]',
32
+ 'layout' => $this->getLayout(),
33
+ 'required' => false,
34
+ 'class' => 'sl-required-entry-multy',
35
+ 'entity_type' => $entity_type
36
+ ))
37
+ ->setFilterWebsiteId(-1)
38
+ ->setFilterId(-1)
39
+ ->setEntityType($entity_type);
40
+
41
+ $fieldsetProfile->addField('content_type', 'hidden', array(
42
+ 'name' => 'content_type',
43
+ 'value' => $this->getContentTypeId()
44
+ ));
45
+
46
+ return parent::_prepareForm();
47
+ }
48
+
49
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tab/Product.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tab_Product
4
+ extends Smartling_Connector_Block_Adminhtml_Instance_Widget
5
+ {
6
+
7
+ public function _construct() {
8
+ parent::_construct();
9
+ $this->_formName = 'website_form_product';
10
+ $this->_formType = 'product';
11
+ }
12
+
13
+ protected function _prepareForm()
14
+ {
15
+
16
+ $form = new Varien_Data_Form(array(
17
+ 'action' => $this->getUrl('*/*/view'),
18
+ 'method' => 'get',
19
+ 'id' => $this->_formName,
20
+ 'name' => $this->_formName
21
+ ));
22
+ $form->setUseContainer(true);
23
+ $this->setForm($form);
24
+
25
+ $fieldset = $form->addFieldset('website', array('legend' => $this->__('Website')));
26
+
27
+ $this->_addElementTypes($fieldset);
28
+
29
+ $fieldset->addField('website_id', 'select', array(
30
+ 'name' => 'website_id',
31
+ 'title' => $this->__('Website'),
32
+ 'label' => $this->__('Website'),
33
+ 'required' => true,
34
+ 'onchange' => 'getProfilesFor' . ucfirst($this->_formType) . '(this)',
35
+ 'values' => Mage::getModel('connector/source_websites')->toOptionArray(true),
36
+ ));
37
+
38
+ $fieldset->addField('content_type', 'hidden', array(
39
+ 'name' => 'content_type',
40
+ 'value' => $this->getContentTypeId()
41
+ ));
42
+
43
+ $fieldsetProfile = $form->addFieldset('profile', array('legend' => $this->__('Profiles')));
44
+
45
+ $fieldsetProfile->addType('profiles','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles');
46
+
47
+ $fieldsetProfile->addField('locales', 'profiles', array(
48
+ 'name' => 'locales[]',
49
+ 'layout' => $this->getLayout(),
50
+ 'required' => false,
51
+ 'class' => 'sl-required-entry-multy',
52
+ 'entity_type' => 'product'
53
+ ));
54
+
55
+ return parent::_prepareForm();
56
+ }
57
+
58
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Tabs.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+ $this->setId('entity_list_tabs');
8
+ $this->setDestElementId('edit_form_container');
9
+ $this->setTitle(Mage::helper('connector')->__('Smartling Entities'));
10
+ }
11
+
12
+ protected function _beforeToHtml() {
13
+ $entityTypes = Mage::getModel('connector/source_content_types')->getList();
14
+
15
+ foreach ($entityTypes as $entityType) {
16
+
17
+ $entityTypeModel = Mage::getModel($entityType['model']);
18
+
19
+ $typeCode = $entityTypeModel->getContentTypeCode();
20
+
21
+ $blockOptions = array(
22
+ 'content_type_id' => $entityType['type_id']
23
+ );
24
+
25
+ if(!mageFindClassFile('Smartling_Connector_Block_Adminhtml_Instance_Tab_' . ucfirst($typeCode))) {
26
+ continue;
27
+ }
28
+
29
+ $block = $this->getLayout()
30
+ ->createBlock('connector/adminhtml_instance_tab_' . $typeCode,
31
+ 'content_name_' . $entityType['type_id'],
32
+ $blockOptions
33
+ );
34
+
35
+ if (!is_object($block)) {
36
+ continue;
37
+ }
38
+
39
+ $this->addTab('type_' . $entityType['type_id'], array(
40
+ 'label' => Mage::helper('connector')->__($entityType['title']),
41
+ 'title' => Mage::helper('connector')->__($entityType['title']),
42
+ 'content' => $block->toHtml() . $block->getScript()
43
+ ));
44
+ }
45
+
46
+ $this->_updateActiveTab();
47
+ return parent::_beforeToHtml();
48
+ }
49
+
50
+ /**
51
+ * Translate html content
52
+ *
53
+ * @param string $html
54
+ * @return string
55
+ */
56
+ protected function _translateHtml($html) {
57
+ Mage::getSingleton('core/translate_inline')->processResponseBody($html);
58
+ return $html;
59
+ }
60
+
61
+ protected function _updateActiveTab() {
62
+ $tabId = $this->getRequest()->getParam('tab');
63
+ if ($tabId) {
64
+ $tabId = preg_replace("#{$this->getId()}_#", '', $tabId);
65
+ if ($tabId) {
66
+ $this->setActiveTab($tabId);
67
+ }
68
+ }
69
+ }
70
+
71
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Instance/Widget.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Instance_Widget extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+ protected $_formName = 'website_form';
6
+
7
+ protected $_formType = '';
8
+
9
+ protected $_scripts = array();
10
+
11
+ protected $_connectionErrorText = '';
12
+
13
+ public function _construct() {
14
+ parent::_construct();
15
+ $this->_connectionErrorText = addslashes(Mage::helper('connector')->__('Sorry. Connection error.'));
16
+ }
17
+
18
+ /**
19
+ *
20
+ * @return string
21
+ */
22
+ public function getScript() {
23
+
24
+ $this->_scripts[] = $this->_formName . "Form = new varienForm('" . $this->_formName . "', '');";
25
+
26
+ $this->_scripts[] = "function getProfilesFor" . ucfirst($this->_formType) . "(selectElement){"
27
+ . " var reloadurl = '" . $this->getUrl('smartling/adminhtml_instance/profiles/type/' . $this->_formType . '/') . "filter_id/' + selectElement.value;"
28
+ . " new Ajax.Request(reloadurl, {"
29
+ . " method: 'get', "
30
+ . " onComplete: function(transport){ "
31
+ . " if(transport.status == 200) { "
32
+ . " var response = transport.responseText; "
33
+ . " $('" . $this->_formType . "_profile_selection').update(response); "
34
+ . " } else { "
35
+ . " $('" . $this->_formType . "_profile_selection').update('" . $this->_connectionErrorText . "'); "
36
+ . " }"
37
+ . " } "
38
+ . " });"
39
+ . " }";
40
+
41
+
42
+ if (is_array($this->_scripts) && sizeof($this->_scripts)) {
43
+ return '<script type="text/javascript">' . "\n" . implode("\n", $this->_scripts) . "\n" . '</script>';
44
+ }
45
+
46
+ }
47
+
48
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Localization/Files/Edit/Form.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Form
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Localization_Files_Edit_Form
9
+ extends Mage_Adminhtml_Block_System_Store_Edit_Form
10
+ {
11
+
12
+ protected function _prepareForm()
13
+ {
14
+ parent::_prepareForm();
15
+
16
+ $widgetForm = Mage_Adminhtml_Block_Widget_Form::_prepareForm();
17
+
18
+ if(Mage::registry('store_type') != 'store') {
19
+ return $widgetForm;
20
+ }
21
+
22
+ $storeModel = Mage::registry('store_data');
23
+
24
+ $form = $this->getForm();
25
+
26
+ $fieldset = $form->getElement('store_fieldset');
27
+
28
+ $fieldset->addField('store_localization_dir', 'select', array(
29
+ 'name' => 'store[store_localization_dir]',
30
+ 'label' => Mage::helper('connector')->__('Localization Directory'),
31
+ 'value' => $storeModel->getStoreLocalizationDir(),
32
+ 'options' => Mage::helper('connector')->getLocalizationDirectoriesList(true),
33
+ 'required' => true,
34
+ 'disabled' => $storeModel->isReadOnly(),
35
+ ));
36
+
37
+ return $widgetForm;
38
+ }
39
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Logs/View.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of View
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Logs_View
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_logs_view";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('Smartling Logs');
17
+
18
+
19
+
20
+ $filename = Mage::getBaseDir('var') . DS . 'log' . DS . Mage::getStoreConfig('dev/smartling/log_file');
21
+
22
+ if(file_exists($filename)) {
23
+ $buttons = array();
24
+
25
+ $buttons[] =
26
+ array(
27
+ 'label' => Mage::helper('connector')->__('Download Log File'),
28
+ 'onclick' => "setLocation('" . $this->getUrl('smartling/adminhtml_translator/downloadlog') . "')"
29
+ );
30
+
31
+ $buttons[] =
32
+ array(
33
+ 'label' => Mage::helper('connector')->__('Remove Log File'),
34
+ 'onclick' => "setLocation('" . $this->getUrl('smartling/adminhtml_translator/removelog') . "')"
35
+ );
36
+
37
+ for($i=0; $i < count($buttons); $i++) {
38
+ Mage_Adminhtml_Block_Widget_Container::addButton('button_' . $i, $buttons[$i], $i, 100, 'header', 'header');
39
+ }
40
+ }
41
+
42
+ parent::__construct();
43
+ $this->_removeButton('add');
44
+
45
+ }
46
+
47
+ public function getCreateUrl()
48
+ {
49
+ return false;
50
+ }
51
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Logs/View/Grid.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Logs_View_Grid
10
+ extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ $this->_typeName = 'smLog';
16
+ $this->_filename = Mage::getStoreConfig('dev/smartling/log_file');
17
+
18
+ parent::__construct();
19
+ $this->setId('smLogGrid');
20
+ $this->setSaveParametersInSession(true);
21
+ $this->setFilterVisibility(false);
22
+ }
23
+
24
+ /**
25
+ * Prepare product attributes grid collection object
26
+ *
27
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
28
+ */
29
+ protected function _prepareCollection()
30
+ {
31
+
32
+ $_pageSize = (int) $this->getParam($this->getVarNameLimit(), $this->_defaultLimit);
33
+ $_currPage = (int) $this->getParam($this->getVarNamePage(), $this->_defaultPage);
34
+
35
+ $collection = Mage::getResourceModel('connector/log_collection');
36
+
37
+ $collection->setPageSize($_pageSize);
38
+ $collection->setCurPage($_currPage);
39
+
40
+ $this->setCollection($collection);
41
+
42
+ return parent::_prepareCollection();
43
+
44
+ }
45
+
46
+ /**
47
+ * Prepare product attributes grid columns
48
+ *
49
+ * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Grid
50
+ */
51
+ protected function _prepareColumns()
52
+ {
53
+
54
+ $this->addColumn('id', array(
55
+ 'header'=> Mage::helper('connector')->__('id'),
56
+ 'sortable'=> true,
57
+ 'filter'=> false,
58
+ 'index' => 'id',
59
+ 'width' => '50px',
60
+ ));
61
+
62
+ $this->addColumn('time', array(
63
+ 'header'=> Mage::helper('connector')->__('Time'),
64
+ 'sortable'=> true,
65
+ 'filter'=> false,
66
+ 'index' => 'time',
67
+ 'width' => '150px',
68
+ 'align' => 'center'
69
+ ));
70
+
71
+ $this->addColumn('level', array(
72
+ 'header'=>Mage::helper('connector')->__('Level'),
73
+ 'index'=>'level',
74
+ 'sortable'=> true,
75
+ 'filter'=> false,
76
+ 'width' => '100px'
77
+ ));
78
+
79
+ $this->addColumn('message', array(
80
+ 'header' => Mage::helper('connector')->__('Message'),
81
+ 'sortable' => true,
82
+ 'filter'=> false,
83
+ 'index'=>'message'
84
+ ));
85
+
86
+ return $this;
87
+ }
88
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Projects
9
+ extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct() {
13
+
14
+ $this->_controller = "adminhtml_projects";
15
+ $this->_blockGroup = "connector";
16
+ $this->_headerText = Mage::helper('connector')->__('Settings profiles');
17
+
18
+ parent::__construct();
19
+ }
20
+
21
+ public function getCreateUrl()
22
+ {
23
+ return $this->getUrl('*/*/new');
24
+ }
25
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit extends Mage_Adminhtml_Block_Widget_Form_Container {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+ $this->_objectId = 'id';
8
+ $this->_controller = 'adminhtml_projects';
9
+ $this->_blockGroup = 'connector';
10
+ $this->_headerText = $this->_getHeaderText();
11
+
12
+ $this->_addButton('save_and_edit_button', array(
13
+ 'label' => Mage::helper('catalog')->__('Save and Continue Edit'),
14
+ 'onclick' => 'editForm.submit(\'' . $this->getSaveAndContinueUrl() . '\')',
15
+ 'class' => 'save'
16
+ ));
17
+ }
18
+
19
+ public function getSaveAndContinueUrl() {
20
+ return $this->getUrl('*/*/save', array(
21
+ '_current' => true,
22
+ 'back' => 'edit',
23
+ ));
24
+ }
25
+
26
+ protected function _getHeaderText() {
27
+ if ($project = Mage::registry('current_projects')) {
28
+ if ($displayName = $project->getName()) {
29
+ return $displayName;
30
+ }
31
+ }
32
+ return $this->__('New Settings Profile');
33
+ }
34
+
35
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Form extends Mage_Adminhtml_Block_Widget_Form {
4
+
5
+ protected function _prepareForm() {
6
+ $form = new Varien_Data_Form(
7
+ array(
8
+ 'id' => 'edit_form',
9
+ 'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
10
+ 'method' => 'post',
11
+ 'enctype' => 'multipart/form-data'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+ $this->setForm($form);
17
+
18
+ return parent::_prepareForm();
19
+ }
20
+
21
+ public function getSaveAndContinueUrl()
22
+ {
23
+ return $this->getUrl('*/*/save', array(
24
+ '_current' => true,
25
+ 'back' => 'edit',
26
+ ));
27
+ }
28
+
29
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form/Element/Profiles.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_Profiles extends Varien_Data_Form_Element_Abstract
4
+ {
5
+ public function __construct($attributes=array())
6
+ {
7
+ parent::__construct($attributes);
8
+ $this->setType('label');
9
+ }
10
+
11
+ /**
12
+ *
13
+ * @return string
14
+ */
15
+ public function getElementHtml()
16
+ {
17
+ return '';
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @param string $idSuffix
23
+ * @return string
24
+ */
25
+ public function getLabelHtml($idSuffix = ''){
26
+ $website_id = $this->getFilterWebsiteId();
27
+
28
+ $localesData = array(
29
+ 'entity_type' => $this->getEntityType(),
30
+ 'filter_id' => $this->getFilterId()
31
+ );
32
+
33
+ $multiselectElement =
34
+ $this->getLayout()->createBlock('connector/adminhtml_projects_locales_form',
35
+ 'locales',
36
+ $localesData);
37
+
38
+ $html = $multiselectElement->toHtml();
39
+
40
+ if(strstr($html, 'input')) {
41
+ $continue_button =
42
+ $this->getLayout()->createBlock('adminhtml/widget_button')
43
+ ->setData(array(
44
+ 'label' => Mage::helper('catalog')->__('Continue'),
45
+ 'onclick' => 'website_form_' . strtolower($this->getEntityType()) . "Form.submit()",
46
+ 'class' => 'save'
47
+ ));
48
+
49
+ $html .= $continue_button->toHtml();
50
+ }
51
+
52
+ return '<p id="' . $this->getEntityType() . '_profile_selection">' . $html . '</p>';
53
+
54
+ }
55
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Form/Element/StoreViewLabel.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_StoreViewLabel extends Varien_Data_Form_Element_Abstract
4
+ {
5
+ public function __construct($attributes=array())
6
+ {
7
+ parent::__construct($attributes);
8
+ $this->setType('label');
9
+ }
10
+
11
+ /**
12
+ *
13
+ * @return string
14
+ */
15
+ public function getElementHtml()
16
+ {
17
+
18
+ $checkboxId = 'is_enabled_' . $this->getStoreId();
19
+ $inputTextId = 'locale_code_' . $this->getStoreId();
20
+ $hiddenInputId = 'project_locale_id_' . $this->getStoreId();
21
+ $values = $this->getValues();
22
+
23
+ $checkbox = $this->addField($checkboxId, 'checkbox', array(
24
+ 'name' => 'is_enabled[' . $this->getStoreId() . ']',
25
+ 'no_span' => true,
26
+ 'class' => 'sl-required-entry-multy'
27
+ ));
28
+
29
+ $textFieldValue = '';
30
+ $hiddenField = '';
31
+
32
+ if($values) {
33
+ $checkbox->setIsChecked(strlen($values->getLocaleCode()) > 0);
34
+ $textFieldValue = $values->getLocaleCode();
35
+
36
+ $hiddenField = $this->addField($hiddenInputId, 'hidden', array(
37
+ 'name' => 'project_locale_identity[' . $this->getStoreId() . ']',
38
+ 'value' => $values->getData('id')
39
+ ))->toHtml();
40
+ }
41
+
42
+ $inputText = $this->addField($inputTextId, 'text', array(
43
+ 'name' => 'locale_code[' . $this->getStoreId() . ']',
44
+ 'title' => Mage::helper('connector')->__('Smartling Locale Code'),
45
+ 'no_span' => true,
46
+ 'value' => $textFieldValue
47
+ ));
48
+
49
+ $html = $checkbox->toHtml()
50
+ . $inputText->toHtml()
51
+ . $hiddenField
52
+ . $this->getAfterElementHtml();
53
+
54
+ return $html;
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param string $idSuffix
60
+ * @return string
61
+ */
62
+ public function getLabelHtml($idSuffix = ''){
63
+
64
+ if (!is_null($this->getLabel())) {
65
+ $html = '<label for="'.$this->getHtmlId() . $idSuffix . '" style="'.$this->getLabelStyle().'">'.$this->getLabel()
66
+ . ( $this->getRequired() ? ' <span class="required">*</span>' : '' ).'</label>'."\n";
67
+ }
68
+ else {
69
+ $html = '';
70
+ }
71
+ return $html;
72
+ }
73
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Tabs.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+ $this->setId('projects_tabs');
8
+ $this->setDestElementId('edit_form');
9
+ $this->setTitle($this->__('Settings Profile'));
10
+ }
11
+
12
+ protected function _beforeToHtml() {
13
+ $this->addTab('general', array(
14
+ 'label' => $this->__('General'),
15
+ 'title' => $this->__('General'),
16
+ 'content' => $this->getLayout()->createBlock('connector/adminhtml_projects_edit_tabs_form')->toHtml(),
17
+ )
18
+ );
19
+
20
+ return parent::_beforeToHtml();
21
+ }
22
+
23
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Edit/Tabs/Form.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Tabs_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+
6
+ /**
7
+ *
8
+ * @return \Mage_Adminhtml_Block_Widget_Form
9
+ */
10
+ protected function _prepareForm() {
11
+
12
+ $website_id = Mage::registry('website_id');
13
+ $websiteInfo = Mage::app()->getWebsite($website_id);
14
+
15
+ $form = new Varien_Data_Form();
16
+
17
+ $this->setForm($form);
18
+
19
+ $fieldset = $form->addFieldset('projects_general', array('legend' => $this->__('General Information')));
20
+
21
+ $this->_addElementTypes($fieldset);
22
+
23
+ $fieldset->addField('name', 'text', array(
24
+ 'name' => 'name',
25
+ 'label' => $this->__('Profile Name'),
26
+ 'title' => $this->__('Profile Name'),
27
+ 'required' => true,
28
+ 'class' => 'required-entry',
29
+ ));
30
+
31
+ $fieldset->addField('active', 'select', array(
32
+ 'name' => 'active',
33
+ 'title' => $this->__('Active'),
34
+ 'label' => $this->__('Active'),
35
+ 'required' => true,
36
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray(),
37
+ ));
38
+
39
+ $fieldset->addField('api_url', 'text', array(
40
+ 'name' => 'api_url',
41
+ 'label' => $this->__('API URL'),
42
+ 'title' => $this->__('API URL'),
43
+ 'required' => true,
44
+ 'class' => 'required-entry',
45
+ ));
46
+
47
+ $fieldset->addField('callback_url', 'text', array(
48
+ 'name' => 'callback_url',
49
+ 'label' => $this->__('Callback URL'),
50
+ 'title' => $this->__('Callback URL'),
51
+ 'required' => false
52
+ ));
53
+
54
+ $fieldset->addField('project_id', 'text', array(
55
+ 'name' => 'project_id',
56
+ 'label' => $this->__('Project Id'),
57
+ 'title' => $this->__('Project Id'),
58
+ 'required' => true,
59
+ 'class' => 'required-entry',
60
+ ));
61
+
62
+ $fieldset->addField('key', 'text', array(
63
+ 'name' => 'key',
64
+ 'label' => $this->__('API Key'),
65
+ 'title' => $this->__('API Key'),
66
+ 'required' => true,
67
+ ));
68
+
69
+ $fieldset->addField('retrieval_type', 'select', array(
70
+ 'name' => 'retrieval_type',
71
+ 'label' => $this->__('Retrieval Type'),
72
+ 'title' => $this->__('Retrieval Type'),
73
+ 'required' => true,
74
+ 'values' => Mage::helper('connector')->getRetrievalTypes()
75
+ ));
76
+
77
+ $fieldset->addField('test_connection', 'button', array('label' => Mage::helper('connector')->__('Test Connection'), 'name' => 'test'))
78
+ ->setRenderer(
79
+ $this->getLayout()->createBlock('connector/adminhtml_system_config_connectionButton')
80
+ );
81
+
82
+ $fieldset->addField('website_id', 'hidden', array(
83
+ 'name' => 'website_id'
84
+ ));
85
+
86
+ $fieldsetMapping = $form->addFieldset('projects_general_maping', array('legend' => $this->__('Mapping for %s', $websiteInfo->getName())));
87
+
88
+ $this->_addElementTypes($fieldsetMapping);
89
+
90
+ $fieldsetMapping->addType('store_view_label','Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_StoreViewLabel');
91
+
92
+
93
+ $storeValues = Mage::helper('connector/data')->getStores($website_id);
94
+
95
+ $localesData = Mage::registry('current_projects_locales');
96
+
97
+ foreach ($storeValues as $storeId => $storeName) {
98
+
99
+ $values = null;
100
+ if(isset($localesData[$storeId])) {
101
+ $values = $localesData[$storeId];
102
+ }
103
+
104
+ $fieldsetMapping->addField('store_view_labels[' . $storeId . ']', 'store_view_label', array(
105
+ 'label' => $storeName,
106
+ 'name' => 'store_view_labels',
107
+ 'required' => false,
108
+ 'values' => $values,
109
+ 'bold' => true,
110
+ 'store_id' => $storeId,
111
+ 'after_element_html' => '<p class="note" style="background-position:17px; padding-left:27px"><span>' . Mage::helper('connector')->__('enter smartling locale code here') . '</span></p>',
112
+ 'class' => 'sl-required-entry-multy'
113
+ ));
114
+ }
115
+
116
+ $formData = array();
117
+
118
+ if ($project = Mage::registry('current_projects')) {
119
+ $formData = $project->getData();
120
+ }
121
+
122
+ $formData['website_id']= $website_id;
123
+
124
+ $form->setValues($formData);
125
+
126
+ return parent::_prepareForm();
127
+ }
128
+
129
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Grid.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Product attributes grid
4
+ *
5
+ * @category Mage
6
+ * @package Mage_Adminhtml
7
+ * @author Smartling
8
+ */
9
+ class Smartling_Connector_Block_Adminhtml_Projects_Grid extends Mage_Adminhtml_Block_Widget_Grid
10
+ {
11
+
12
+ public function __construct()
13
+ {
14
+ parent::__construct();
15
+ $this->setId('projectsGrid');
16
+ $this->setDefaultSort('id');
17
+ $this->setDefaultDir('ASC');
18
+ }
19
+
20
+ /**
21
+ * Prepare projects collection
22
+ *
23
+ * @return \Smartling_Connector_Block_Adminhtml_Projects_Grid
24
+ */
25
+ protected function _prepareCollection()
26
+ {
27
+ $resource = Mage::getSingleton('core/resource');
28
+ $websiteTable = $resource->getTableName('core_website');
29
+
30
+ $collection = Mage::getResourceModel('connector/projects_collection');
31
+
32
+ $collection->getSelect()
33
+ ->joinLeft(array("t1" => $websiteTable),
34
+ "main_table.website_id = t1.website_id",
35
+ array("website_name" => "t1.name"));
36
+
37
+
38
+ $this->setCollection($collection);
39
+
40
+ return parent::_prepareCollection();
41
+ }
42
+
43
+ /**
44
+ * Prepare project grid columns
45
+ *
46
+ * @return \Smartling_Connector_Block_Adminhtml_Projects_Grid
47
+ */
48
+ protected function _prepareColumns()
49
+ {
50
+
51
+
52
+ $this->addColumn('name', array(
53
+ 'header'=>Mage::helper('connector')->__('Project Name'),
54
+ 'index'=>'name',
55
+ 'width' => '250px',
56
+ ));
57
+
58
+ $this->addColumn('project_id', array(
59
+ 'header'=>Mage::helper('connector')->__('Project Id'),
60
+ 'index'=>'project_id',
61
+ 'width' => '250px',
62
+ ));
63
+
64
+ $this->addColumn('key', array(
65
+ 'header'=>Mage::helper('connector')->__('API Key'),
66
+ 'index'=>'key',
67
+ 'width' => '400px'
68
+ ));
69
+
70
+ $this->addColumn('website_name', array(
71
+ 'header'=>Mage::helper('connector')->__('Website'),
72
+ 'index'=>'website_name',
73
+ 'width' => '70px',
74
+ 'filter' => false,
75
+ 'sortable' => true,
76
+ ));
77
+
78
+ $this->addColumn('active', array(
79
+ 'header'=>Mage::helper('connector')->__('Active'),
80
+ 'index'=>'active',
81
+ 'type' => 'options',
82
+ 'options' => array(
83
+ '1' => Mage::helper('connector')->__('Yes'),
84
+ '0' => Mage::helper('connector')->__('No'),
85
+ ),
86
+ 'width' => '50px'
87
+ ));
88
+
89
+ $this->addColumn('action', array(
90
+ 'header' => Mage::helper('connector')->__('Action'),
91
+ 'width' => '50px',
92
+ 'type' => 'action',
93
+ 'getter' => 'getId',
94
+ 'actions' => array(
95
+ array(
96
+ 'caption' => Mage::helper('connector')->__('Edit'),
97
+ 'url' => array(
98
+ 'base'=>'*/*/edit',
99
+ ),
100
+ 'field' => 'id'
101
+ ),
102
+ ),
103
+ 'filter' => false,
104
+ 'sortable' => false,
105
+ 'index' => 'id',
106
+ ));
107
+
108
+ $this->addColumn('delete',
109
+ array(
110
+ 'header' => $this->__('Delete'),
111
+ 'index' => 'id',
112
+ 'width' => '50px',
113
+ 'type' => 'action',
114
+ 'actions' => array(array(
115
+ 'caption' => $this->__('Delete'),
116
+ 'url' => array(
117
+ 'base' => '*/*/delete',
118
+ ),
119
+ 'confirm' => $this->__('Are you sure?'),
120
+ 'field' => 'id'
121
+ )),
122
+ 'filter' => false,
123
+ 'sortable' => false,
124
+ ));
125
+
126
+ return $this;
127
+ }
128
+
129
+ /**
130
+ * Return url of given row
131
+ *
132
+ * @return string
133
+ */
134
+ public function getRowUrl($row)
135
+ {
136
+ return false;
137
+ }
138
+
139
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/Locales/Form.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Projects Locales Form
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_Projects_Locales_Form
9
+ extends Mage_Adminhtml_Block_Widget_Form
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var int
15
+ */
16
+ protected $_contentTypeId;
17
+
18
+ /**
19
+ *
20
+ * @param array $data
21
+ */
22
+ public function __construct(array $data) {
23
+ parent::__construct($data);
24
+ $this->setReadyStatus(false);
25
+
26
+ if($this->getEntityType() && $this->getFilterId()) {
27
+
28
+ try {
29
+
30
+ $filterClass = 'connector/projects_filter_' . $this->getEntityType();
31
+
32
+ $filterModel = Mage::getModel($filterClass);
33
+ if(($filterModel instanceof Smartling_Connector_Model_Projects_Filter) === false) {
34
+ Mage::getSingleton('adminhtml/session')->addError(
35
+ Mage::helper('connector')->__("Application error. Please check smartling log to see details.")
36
+ );
37
+ Mage::throwException("Class [" . $filterClass . "] must be instance of Smartling_Connector_Model_Projects_Filter");
38
+ }
39
+
40
+ $options = $filterModel->getAvailableProjects($this->getFilterId());
41
+
42
+ if(sizeof($options) && $this->getEntityType()) {
43
+ $this->_formName = 'website_form_' . $this->getEntityType();
44
+
45
+ $this->setOptions($options);
46
+
47
+ $this->setTemplate('connector/adminhtml/edit/tab/bulk_translations.phtml');
48
+ $this->setReadyStatus(true);
49
+ }
50
+ } catch (Mage_Core_Exception $ex) {
51
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @param string $html
59
+ * @return string
60
+ */
61
+ protected function _afterToHtml($html) {
62
+
63
+ $type = $this->getEntityType();
64
+
65
+ if(!$type) {
66
+ return Mage::helper('connector')->__('Please select entity type');
67
+ }
68
+
69
+ $filter_id = $this->getFilterId();
70
+
71
+ if(!$filter_id) {
72
+ return Mage::getModel('connector/projects_filter_' . $type)->getMessageOnEmptyRequest();
73
+ }
74
+
75
+ $options = $this->getOptions();
76
+
77
+ if(!sizeof($options)) {
78
+ return Mage::helper('connector')
79
+ ->__('Sorry. No one profile for this item is available.');
80
+ }
81
+
82
+ return $html;
83
+ }
84
+
85
+ /**
86
+ * Prepare label for tab
87
+ *
88
+ * @return string
89
+ */
90
+ public function getTabLabel()
91
+ {
92
+ return Mage::helper('connector')->__('Smartling Translations');
93
+ }
94
+
95
+ /**
96
+ * Prepare title for tab
97
+ *
98
+ * @return string
99
+ */
100
+ public function getTabTitle()
101
+ {
102
+ return Mage::helper('connector')->__('Smartling Translations');
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @param int $contentTypeId
108
+ * @param int $content_id
109
+ * @return array
110
+ */
111
+ public function findAvailableLocales($contentTypeId = '', $website_ids = array()) {
112
+ return Mage::getModel('connector/projects')->getProjectsLocales($contentTypeId, $content_id, $website_ids);
113
+ }
114
+
115
+ /**
116
+ *
117
+ * @return int
118
+ */
119
+ public function getContentTypeId() {
120
+ return $this->_contentTypeId;
121
+ }
122
+
123
+ /**
124
+ *
125
+ * @return string
126
+ */
127
+ public function getTitle() {
128
+ return Mage::helper('connector')->__("Smartling Translation Actions");
129
+ }
130
+
131
+ public function getFormName() {
132
+ return $this->_formName;
133
+ }
134
+
135
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_New extends Mage_Adminhtml_Block_Widget_Form_Container
4
+ {
5
+
6
+ public function __construct() {
7
+ parent::__construct();
8
+ $this->_objectId = 'id';
9
+ $this->_controller = 'adminhtml_projects';
10
+ $this->_blockGroup = 'connector';
11
+ $this->_headerText = $this->_getHeaderText();
12
+
13
+ $this->_removeButton('save');
14
+ }
15
+
16
+ protected function _getHeaderText() {
17
+ return $this->__('Profile Website');
18
+ }
19
+
20
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Form.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_New_Form extends Mage_Adminhtml_Block_Widget_Form {
4
+
5
+ protected function _prepareForm() {
6
+ $form = new Varien_Data_Form(
7
+ array(
8
+ 'id' => 'edit_form',
9
+ 'action' => $this->getUrl('*/*/edit', array('id' => $this->getRequest()->getParam('id'))),
10
+ 'method' => 'post',
11
+ 'enctype' => 'multipart/form-data'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+ $this->setForm($form);
17
+
18
+ return parent::_prepareForm();
19
+ }
20
+
21
+ public function getSaveAndContinueUrl()
22
+ {
23
+ return $this->getUrl('*/*/edit', array(
24
+ '_current' => true,
25
+ 'back' => 'edit',
26
+ ));
27
+ }
28
+
29
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Form/Element/StoreViewLabel.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_Edit_Form_Element_StoreViewLabel extends Varien_Data_Form_Element_Abstract
4
+ {
5
+ public function __construct($attributes=array())
6
+ {
7
+ parent::__construct($attributes);
8
+ $this->setType('label');
9
+ }
10
+
11
+ /**
12
+ *
13
+ * @return string
14
+ */
15
+ public function getElementHtml()
16
+ {
17
+
18
+ $checkboxId = 'is_enabled_' . $this->getStoreId();
19
+ $inputTextId = 'locale_code_' . $this->getStoreId();
20
+ $hiddenInputId = 'project_locale_id_' . $this->getStoreId();
21
+ $values = $this->getValues();
22
+
23
+ $checkbox = $this->addField($checkboxId, 'checkbox', array(
24
+ 'name' => 'is_enabled[' . $this->getStoreId() . ']',
25
+ 'no_span' => true,
26
+ 'class' => 'sl-required-entry-multy'
27
+ ));
28
+
29
+ $textFieldValue = '';
30
+ $hiddenField = '';
31
+
32
+ if($values) {
33
+ $checkbox->setIsChecked(strlen($values->getLocaleCode()) > 0);
34
+ $textFieldValue = $values->getLocaleCode();
35
+
36
+ $hiddenField = $this->addField($hiddenInputId, 'hidden', array(
37
+ 'name' => 'project_locale_identity[' . $this->getStoreId() . ']',
38
+ 'value' => $values->getData('id')
39
+ ))->toHtml();
40
+ }
41
+
42
+ $inputText = $this->addField($inputTextId, 'text', array(
43
+ 'name' => 'locale_code[' . $this->getStoreId() . ']',
44
+ 'title' => Mage::helper('connector')->__('Smartling Locale Code'),
45
+ 'no_span' => true,
46
+ 'value' => $textFieldValue
47
+ ));
48
+
49
+ $html = $checkbox->toHtml()
50
+ . $inputText->toHtml()
51
+ . $hiddenField
52
+ . $this->getAfterElementHtml();
53
+
54
+ return $html;
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param string $idSuffix
60
+ * @return string
61
+ */
62
+ public function getLabelHtml($idSuffix = ''){
63
+
64
+ if (!is_null($this->getLabel())) {
65
+ $html = '<label for="'.$this->getHtmlId() . $idSuffix . '" style="'.$this->getLabelStyle().'">'.$this->getLabel()
66
+ . ( $this->getRequired() ? ' <span class="required">*</span>' : '' ).'</label>'."\n";
67
+ }
68
+ else {
69
+ $html = '';
70
+ }
71
+ return $html;
72
+ }
73
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Tabs.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_New_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
4
+ {
5
+
6
+ public function __construct() {
7
+ parent::__construct();
8
+ $this->setId('projects_tabs');
9
+ $this->setDestElementId('edit_form');
10
+ $this->setTitle($this->__('Settings Profile'));
11
+ }
12
+
13
+ protected function _beforeToHtml() {
14
+ $this->addTab('general', array(
15
+ 'label' => $this->__('Settings'),
16
+ 'title' => $this->__('Settings'),
17
+ 'content' => $this->getLayout()->createBlock('connector/adminhtml_projects_new_tabs_form')->toHtml(),
18
+ )
19
+ );
20
+
21
+ return parent::_beforeToHtml();
22
+ }
23
+
24
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/Projects/New/Tabs/Form.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Block_Adminhtml_Projects_New_Tabs_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+
6
+ protected function _prepareLayout()
7
+ {
8
+ $this->setChild('continue_button',
9
+ $this->getLayout()->createBlock('adminhtml/widget_button')
10
+ ->setData(array(
11
+ 'label' => Mage::helper('catalog')->__('Continue'),
12
+ 'onclick' => "this.form.submit()",
13
+ 'class' => 'save'
14
+ ))
15
+ );
16
+ return parent::_prepareLayout();
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @return \Mage_Adminhtml_Block_Widget_Form
22
+ */
23
+ protected function _prepareForm() {
24
+
25
+ $form = new Varien_Data_Form(array(
26
+ 'action' => $this->getUrl('*/*/view'),
27
+ 'method' => 'post',
28
+ 'id' => 'website_form'
29
+ ));
30
+ $form->setUseContainer(true);
31
+ $this->setForm($form);
32
+
33
+ $fieldset = $form->addFieldset('profile_website', array('legend' => $this->__('Profile Website Settings')));
34
+
35
+ $this->_addElementTypes($fieldset);
36
+
37
+ $fieldset->addField('website_id', 'select', array(
38
+ 'name' => 'website_id',
39
+ 'title' => $this->__('Website'),
40
+ 'label' => $this->__('Website'),
41
+ 'required' => true,
42
+ 'values' => Mage::getModel('connector/source_websites')->toOptionArray(),
43
+ ));
44
+
45
+ $fieldset->addField('continue_button', 'note', array(
46
+ 'text' => $this->getChildHtml('continue_button'),
47
+ ));
48
+
49
+ return parent::_prepareForm();
50
+ }
51
+
52
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/ConnectionButton.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of ConnectionButton
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_System_Config_ConnectionButton
9
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
10
+ {
11
+
12
+ /**
13
+ *
14
+ * set template
15
+ */
16
+ public function _construct() {
17
+ $this->setTemplate('connector/adminhtml/system/config/connectionbutton.phtml');
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @param \Varien_Data_Form_Element_Abstract $element
23
+ * @return string
24
+ */
25
+ protected function _getElementHtml(\Varien_Data_Form_Element_Abstract $element) {
26
+ return $this->_toHtml();
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @return string
32
+ */
33
+ public function getServiceUrl(){
34
+ return $this->getUrl('smartling/adminhtml_service/configTest', array('limit' => 1));
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @return string
40
+ */
41
+ public function getButton(){
42
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
43
+ ->setType('button')
44
+ ->setClass('scalable')
45
+ ->setLabel('Test')
46
+ ->setOnClick("testConnection()");
47
+
48
+ return $button->toHtml();
49
+ }
50
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/ContentFields.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of ContentFields
5
+ * @deprecated since version 0.1.7
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_System_Config_ContentFields
9
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
10
+ {
11
+
12
+ const CONFIG_PATH = 'smartling/';
13
+
14
+ /**
15
+ * stores config data
16
+ *
17
+ * @var array
18
+ */
19
+ protected $_values = null;
20
+
21
+ /**
22
+ * stores option values data from source model
23
+ *
24
+ * @var array
25
+ */
26
+ protected $_options = array();
27
+
28
+ /**
29
+ * stores second part of path for config
30
+ *
31
+ * @var string
32
+ */
33
+ protected $_path = '';
34
+
35
+ /**
36
+ *
37
+ * Define template
38
+ */
39
+ protected function _construct() {
40
+ $this->setTemplate('connector/adminhtml/system/config/contentfields.phtml');
41
+ parent::_construct();
42
+ }
43
+
44
+ /**
45
+ *
46
+ * @param Varien_Data_Form_Element_Abstract $element
47
+ * @return string
48
+ */
49
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
50
+ $this->_path = $this->_getConfigPath($element->getId());
51
+ $this->_options = $element->getValues();
52
+
53
+ //get selected values from config data
54
+ $this->_getCheckedValues();
55
+
56
+ $this->setNamePrefix($element->getName())
57
+ ->setHtmlId($element->getHtmlId());
58
+ return $this->_toHtml();
59
+ }
60
+
61
+ /**
62
+ *
63
+ * @return array
64
+ */
65
+ public function getValues(){
66
+ return $this->_options;
67
+ }
68
+
69
+ /**
70
+ *
71
+ * @param string $value
72
+ * @return bool
73
+ */
74
+ public function isChecked($value){
75
+ return in_array($value, $this->_values);
76
+ }
77
+
78
+ /**
79
+ * Get checked values from config
80
+ *
81
+ * @return string | null
82
+ */
83
+ protected function _getCheckedValues(){
84
+ $data = Mage::getStoreConfig(self::CONFIG_PATH . $this->_path);
85
+ if (is_null($data) || empty($data)){
86
+ $data = '';
87
+ }
88
+ $this->_values = explode(",", $data);
89
+ return $this->_values;
90
+ }
91
+
92
+ /**
93
+ * define config path
94
+ *
95
+ * @return string
96
+ */
97
+ protected function _getConfigPath($elementId){
98
+ $pathMap = array(
99
+ 'smartling_cms_page_settings_fields_to_translate' => 'cms_page_settings/fields_to_translate',
100
+ 'smartling_cms_block_settings_fields_to_translate' => 'cms_block_settings/fields_to_translate',
101
+ 'smartling_product_settings_attributes_to_translate' => 'product_settings/attributes_to_translate',
102
+ 'smartling_category_settings_attributes_to_translate' => 'category_settings/attributes_to_translate'
103
+ );
104
+ if (isset($pathMap[$elementId])){
105
+ return $pathMap[$elementId];
106
+ }
107
+ return '';
108
+ }
109
+ }
app/code/community/Smartling/Connector/Block/Adminhtml/System/Config/Version.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Module Version Info
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Block_Adminhtml_System_Config_Version
9
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
10
+ {
11
+ /**
12
+ *
13
+ * @param \Varien_Data_Form_Element_Abstract $element
14
+ * @return string
15
+ */
16
+ protected function _getElementHtml(\Varien_Data_Form_Element_Abstract $element) {
17
+ return (string) Mage::getConfig()->getNode()->modules->Smartling_Connector->version;
18
+ }
19
+
20
+ }
app/code/community/Smartling/Connector/Helper/Data.php ADDED
@@ -0,0 +1,613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Data
5
+ *
6
+ * @author Itdelight
7
+ */
8
+ class Smartling_Connector_Helper_Data
9
+ extends Mage_Core_Helper_Data
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @return string
15
+ */
16
+ public function getConfig($code, $configPath){
17
+ $path = $code . "/" . $configPath;
18
+ return Mage::app()->getStore()->getConfig($path);
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param string $json
24
+ * @return boolean
25
+ */
26
+ public function isJson($json){
27
+ if (json_decode($json) !== null && is_object(json_decode($json))){
28
+ return true;
29
+ }
30
+ return false;
31
+ }
32
+
33
+ /**
34
+ *
35
+ * @param array $stores
36
+ */
37
+ public function prepareLocalesForSave($stores){
38
+ if (!is_array($stores)){
39
+ Mage::log ('uncorrect data for stores', null, 'SmartlingLog.log');
40
+ return false;
41
+ }
42
+
43
+ }
44
+
45
+ /**
46
+ *
47
+ * @param string $identifier
48
+ * @return string
49
+ */
50
+ public function getFileUri($identifier){
51
+ $timetamp = time();
52
+ $fileType = Mage::getStoreConfig('smartling/settings/file_type');
53
+ return $identifier . "_" . $timetamp . "." . $fileType;
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @param string $localeCode
59
+ * @return array
60
+ */
61
+ public function getStoresIdByLocale($localeCode) {
62
+ $stores = array();
63
+ $locales = $this->getLocaleMap();
64
+
65
+ foreach ($locales as $key => $value){
66
+ if ($value == $localeCode){
67
+ $stores[] = $key;
68
+ }
69
+ }
70
+
71
+ return $stores;
72
+ }
73
+
74
+ /**
75
+ *
76
+ * @param array $storeIds
77
+ * @return array
78
+ */
79
+ public function getStoresLocaleByIds($storeIds){
80
+ $locales = $this->getLocaleMap();
81
+
82
+ foreach ($locales as $storeId => $localeName){
83
+ if (!in_array($storeId, $storeIds)){
84
+ unset ($locales[$storeId]);
85
+ }
86
+ }
87
+
88
+ return $locales;
89
+ }
90
+
91
+ /**
92
+ *
93
+ * @param int $contentTypeId
94
+ * @param int $content_id
95
+ * @return array
96
+ */
97
+ public function getLocaleMap($contentTypeId = '', $content_id = ''){
98
+ return Mage::getModel('connector/projects')->getProjectsLocales($contentTypeId, $content_id);
99
+ }
100
+
101
+ /**
102
+ *
103
+ * @param string $type
104
+ * @return int
105
+ */
106
+ public function findTypeIdByTypeName($type){
107
+ $contentType = Mage::getModel('connector/content_types')->getCollection()
108
+ ->addFieldToFilter('type_name', array('eq' => $type));
109
+ if ($contentType->getSize() == 0){
110
+ Mage::getSingleton('admin/session')->addError(
111
+ 'Content type does not exists'
112
+ );
113
+ return;
114
+ }
115
+ $type = $contentType->getFirstItem();
116
+ return $type->getTypeId();
117
+ }
118
+
119
+ /**
120
+ *
121
+ * @param string $type
122
+ * @return string
123
+ */
124
+ public function findContentTypeModel($type){
125
+ $contentModel = $this->_getContentType($type)->getModel();
126
+ return $contentModel;
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @param string $type
132
+ * @return Mage_Core_Model_Resource_Db_Collection
133
+ */
134
+ protected function _getContentType($type){
135
+ $contentType = Mage::getModel('connector/content_types')->getCollection()
136
+ ->addFieldToFilter('type_name', array('eq' => $type));
137
+ if ($contentType->getSize() == 0){
138
+ Mage::getSingleton('admin/session')->addError(
139
+ 'Content type does not exists'
140
+ );
141
+ }
142
+
143
+ $type = $contentType->getFirstItem();
144
+ return $type;
145
+ }
146
+
147
+ /**
148
+ *
149
+ * @return int
150
+ */
151
+ public function getSubmitter(){
152
+ $user = Mage::getSingleton('admin/session')->getUser();
153
+ if(is_object($user)) {
154
+ return $user->getId();
155
+ } else {
156
+ return 0;
157
+ }
158
+ }
159
+
160
+ /**
161
+ *
162
+ * @param int $entityType
163
+ * @param array $attributes
164
+ * @return Mage_Eav_Model_Resource_Entity_Attribute_Collection
165
+ * @deprecated since version 0.1.7
166
+ */
167
+ public function getAttributesForTranslation($entityType, $attributes){
168
+ $attributesCollection = Mage::getResourceModel('eav/entity_attribute_collection')
169
+ ->setEntityTypeFilter($entityType)
170
+ ->addFieldToFilter('main_table.attribute_id', array('in' => $attributes));
171
+
172
+
173
+ return $attributesCollection;
174
+ }
175
+
176
+ /**
177
+ * @deprecated since version 0.2.3
178
+ * @return int
179
+ */
180
+ public function getDefaultStoreId(){
181
+ $storeId = Mage::app()->getDefaultStoreView()->getId();
182
+ return $storeId;
183
+ }
184
+
185
+ /**
186
+ *
187
+ * @return boolean
188
+ */
189
+ public function showTranslationTab(){
190
+ $storeId = Mage::app()->getRequest()->getParam('store', 0);
191
+ if ($storeId && $storeId !== 0){
192
+ return false;
193
+ }
194
+ return true;
195
+ }
196
+
197
+ /**
198
+ *
199
+ * @param string $table you can use pattern with '/' or '_' symbols ex 'cms/page' or 'cms_page'
200
+ * @return array
201
+ */
202
+ public function getFields($table){
203
+ $allowedFieldsTypes = array('varchar', 'text', 'mediumtext');
204
+ $fields = array();
205
+ $adapter = Mage::getSingleton('core/resource')->getConnection('core_read');
206
+ $tableName = $adapter->getTableName($table);
207
+ $tableFields = $adapter->describeTable($tableName);
208
+ foreach ($tableFields as $_field){
209
+ if (in_array($_field['DATA_TYPE'], $allowedFieldsTypes)){
210
+ $fields[] = $_field['COLUMN_NAME'];
211
+ }
212
+ }
213
+ return $fields;
214
+ }
215
+
216
+ /**
217
+ * Get entity ID by code
218
+ * @param string $code
219
+ * @return int
220
+ */
221
+ public function getEntityTypeId($code) {
222
+ $entityType = Mage::getModel('eav/config')->getEntityType($code);
223
+ $entityTypeId = $entityType->getEntityTypeId();
224
+
225
+ return (int)$entityTypeId;
226
+ }
227
+
228
+ /**
229
+ * Return all stores view exclude default
230
+ * @param int $website_id
231
+ * @param boolean $withDefault
232
+ * @return array
233
+ */
234
+ public function getStores($website_id, $withDefault = false) {
235
+
236
+ $options = array();
237
+ $groupCollection = array();
238
+
239
+ foreach (Mage::app()->getWebsites() as $website) {
240
+ if($website->getId() != $website_id) continue;
241
+
242
+ foreach ($website->getGroups() as $group) {
243
+ $groupCollection[$group->getId()] = $group;
244
+ }
245
+ }
246
+
247
+ $storeCollection = Mage::app()->getStores();
248
+ $websiteCollection = Mage::app()->getWebsites();
249
+ $nonEscapableNbspChar = html_entity_decode('&#160;', ENT_NOQUOTES, 'UTF-8');
250
+
251
+ foreach ($websiteCollection as $website) {
252
+ $websiteShow = false;
253
+ foreach ($groupCollection as $group) {
254
+ if ($website->getId() != $group->getWebsiteId()) {
255
+ continue;
256
+ }
257
+ $groupShow = false;
258
+ foreach ($storeCollection as $store) {
259
+ if ($group->getId() != $store->getGroupId()) {
260
+ continue;
261
+ }
262
+ $options[$store->getId()] =
263
+ $group->getName() . '<br>'
264
+ . str_repeat($nonEscapableNbspChar, 8)
265
+ . '<b>' . $store->getName() . '</b>';
266
+ }
267
+
268
+ }
269
+ }
270
+
271
+ if(!$withDefault) {
272
+ $defaultStoreId = self::getSourceStoreView();
273
+ unset($options[$defaultStoreId]);
274
+ }
275
+
276
+ return $options;
277
+ }
278
+
279
+ /**
280
+ * Return Id of default source view for Smartling module
281
+ * @return int
282
+ * @deprecated since version 0.2.1
283
+ */
284
+ public function getSourceStoreView($store_group_id) {
285
+
286
+ $defaultStoreId = Mage::getStoreConfig('smartling/settings/source_store_view');
287
+
288
+ if(!$defaultStoreId) {
289
+ $defaultStoreId = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();
290
+ }
291
+
292
+ return (int)$defaultStoreId;
293
+ }
294
+
295
+ /**
296
+ *
297
+ * @return array
298
+ */
299
+ public function getRetrievalTypes() {
300
+ return
301
+ array(
302
+ 'published' => 'Published',
303
+ 'pending' => 'Pending',
304
+ 'pseudo' => 'Pseudo'
305
+ );
306
+ }
307
+
308
+ /**
309
+ *
310
+ * @return array
311
+ */
312
+ public function getDefaultRetrievalType() {
313
+ return 'published';
314
+ }
315
+
316
+ /**
317
+ * @param string $val
318
+ * @return boolean
319
+ */
320
+ public function validateProjectId($val) {
321
+ return (bool)(preg_match('/^[a-zA-Z0-9]*$/', $val));
322
+ }
323
+
324
+ /**
325
+ * @param string $val
326
+ * @return boolean
327
+ */
328
+ public function validateApiKey($val) {
329
+ return (bool)(preg_match('/^\w{8}(?:-\w{4}){3}-\w{12}$/', $val));
330
+ }
331
+
332
+ /**
333
+ * Log messages to specific file
334
+ *
335
+ * @param string $message
336
+ * @param int $level
337
+ */
338
+ public function log($message, $level = Zend_log::INFO) {
339
+
340
+ $log_file = Mage::getStoreConfig('dev/smartling/log_file');
341
+ $log_level = Mage::getStoreConfig('dev/smartling/log_level');
342
+ $writeLog = false;
343
+
344
+ if(!$log_file) {
345
+ $log_file = 'smartling.log';
346
+ }
347
+
348
+ $levelErrors = array(
349
+ Zend_log::EMERG,
350
+ Zend_log::ALERT,
351
+ Zend_log::CRIT,
352
+ Zend_log::ERR,
353
+ Zend_log::WARN
354
+ );
355
+
356
+ $levelInfo = array(
357
+ Zend_log::NOTICE,
358
+ Zend_log::INFO
359
+ );
360
+
361
+ // log errors only
362
+ if(in_array($log_level, $levelErrors) && in_array($level, $levelErrors)) {
363
+ $writeLog = true;
364
+ }
365
+
366
+ // log info and errors
367
+ if(in_array($log_level, $levelInfo) && in_array($level, $levelInfo)
368
+ || in_array($level, $levelErrors)) {
369
+ $writeLog = true;
370
+ }
371
+
372
+ // if debug level then log everything
373
+ if($log_level == Zend_log::DEBUG) {
374
+ $writeLog = true;
375
+ }
376
+
377
+ if($writeLog) {
378
+
379
+ $trace = debug_backtrace();
380
+ $mock_data = Mage::getStoreConfig('dev/smartling/mock_data');
381
+
382
+ $lineMessage = $trace[0]['file'] . '. Line: ' .$trace[0]['line'];
383
+
384
+ if($mock_data == 1) {
385
+ $message = 'Mock mode is enabled. ' . $message;
386
+ }
387
+
388
+ Mage::log($message . ' in ' . $lineMessage, $level, $log_file);
389
+ }
390
+ }
391
+
392
+ /**
393
+ *
394
+ * @return array
395
+ */
396
+ public function getLogLevels() {
397
+ $options =
398
+ array(
399
+ Zend_log::EMERG => 'Emergency',
400
+ Zend_log::ALERT => 'Alert',
401
+ Zend_log::CRIT => 'Critical',
402
+ Zend_log::ERR => 'Error',
403
+ Zend_log::WARN => 'Warning',
404
+ Zend_log::NOTICE => 'Notice',
405
+ Zend_log::INFO => 'Informational',
406
+ Zend_log::DEBUG => 'Debug'
407
+ );
408
+
409
+ return $options;
410
+ }
411
+
412
+ /**
413
+ *
414
+ * @param int $completedStringCount
415
+ * @param int $stringCount
416
+ * @return int
417
+ */
418
+ public function calculatePercent($completedStringCount, $stringCount) {
419
+
420
+ if($stringCount == 0) {
421
+ return 0;
422
+ }
423
+
424
+ $percent = ($completedStringCount / $stringCount) * 100;
425
+
426
+ return round($percent);
427
+ }
428
+
429
+ /**
430
+ * Launch cron job
431
+ * @param string $key
432
+ */
433
+ public function scheduleNow($key = 'upload_bulk_content') {
434
+
435
+ $schedule = Mage::getModel('cron/schedule'); /* @var $schedule Aoe_Scheduler_Model_Schedule */
436
+
437
+ if( ($schedule instanceof Aoe_Scheduler_Model_Schedule) == false ) {
438
+ return false;
439
+ }
440
+
441
+ $schedule->setJobCode($key)
442
+ ->runNow(false) // without trying to lock the job
443
+ ->save();
444
+
445
+ $messages = $schedule->getMessages();
446
+
447
+ if ($schedule->getStatus() == Mage_Cron_Model_Schedule::STATUS_SUCCESS) {
448
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Ran "%s" (Duration: %s sec)', $key, intval($schedule->getDuration())));
449
+ if ($messages) {
450
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('"%s" messages:<pre>%s</pre>', $key, $messages));
451
+ }
452
+ } else {
453
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Error while running "%s"', $key));
454
+ if ($messages) {
455
+ Mage::getSingleton('adminhtml/session')->addError($this->__('"%s" messages:<pre>%s</pre>', $key, $messages));
456
+ }
457
+ }
458
+
459
+ }
460
+
461
+ /**
462
+ * Merge original and received data for options
463
+ * @param Mage_Catalog_Model_Resource_Eav_Attribute $model
464
+ * @param type $data
465
+ * @return void
466
+ */
467
+ public function mergeAttributesOptions(Mage_Catalog_Model_Resource_Eav_Attribute &$model, &$data, $destinationStoreId) {
468
+
469
+ /** @var $helperCatalog Mage_Catalog_Helper_Data */
470
+ $helperCatalog = Mage::helper('catalog');
471
+
472
+ // set default value
473
+ $model->setStoreId(0);
474
+
475
+ /** @var array $options - List of original options */
476
+ $options = array($model->getSource()->getAllOptions(false));
477
+
478
+ // [[ re-format received data option array
479
+ $optionValues = array();
480
+
481
+ if (!empty($data['option']) && is_array($data['option'])) {
482
+ foreach ($data['option'] as $key => $values) {
483
+ $optionValues['option']['value'][$key][$destinationStoreId] = $helperCatalog->stripTags($values['value']);
484
+ }
485
+ }
486
+
487
+ unset($data['options_values']);
488
+ $data['option'] = $optionValues['option'];
489
+ // ]] re-format received data option array
490
+
491
+ $frontend_label = $data['frontend_label'];
492
+ $data['frontend_label'] = array($model->getStoreLabel(0));
493
+
494
+ foreach (Mage::app()->getWebsites() as $website) {
495
+ foreach ($website->getGroups() as $group) {
496
+ $stores = $group->getStores();
497
+
498
+ foreach ($stores as $store) {
499
+
500
+ $storeId = $store->getId();
501
+
502
+ $model->setStoreId($storeId);
503
+ $options[$storeId] = $model->getSource()->getAllOptions(false);
504
+
505
+ if($storeId != $destinationStoreId) {
506
+ $data['frontend_label'][$storeId] = $model->getStoreLabel($storeId);
507
+ } else {
508
+ $data['frontend_label'][$storeId] = $frontend_label;
509
+ }
510
+ }
511
+ }
512
+ }
513
+ ksort($data['frontend_label']);
514
+
515
+ //[[ merge original and received options
516
+ foreach ($options as $storeId => $storeOptions) {
517
+ foreach ($storeOptions as $value) {
518
+ $option_id = $value['value'];
519
+
520
+ if(!isset($data['option']['value'][$option_id][$storeId])) {
521
+ $data['option']['value'][$option_id][$storeId] = $value['label'];
522
+ }
523
+
524
+ ksort($data['option']['value'][$option_id]);
525
+ }
526
+ }
527
+ //]] merge original and received options
528
+
529
+ //[[ set option sort order
530
+ $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')
531
+ ->setAttributeFilter($model->getId())
532
+ ->setPositionOrder('desc', true)
533
+ ->load();
534
+
535
+ foreach ($optionCollection as $option) {
536
+ $data['option']['order'][$option->getId()] = $option->getSortOrder();
537
+ }
538
+ //]] set option sort order
539
+
540
+ return $data;
541
+
542
+ }
543
+
544
+ /**
545
+ *
546
+ * @return array
547
+ */
548
+ public function getLocalizationDirectoriesList($showSelectText = false) {
549
+
550
+ $options = array();
551
+
552
+ if($showSelectText) {
553
+ $options[] = Mage::helper('connector')->__('Please select directory of localization dir');
554
+ }
555
+
556
+ $locale = Mage::getBaseDir('locale');
557
+
558
+ $dirs = new Varien_Directory_Collection($locale, false);
559
+ foreach ($dirs as $item) {
560
+ $code = $item->getDirName();
561
+ $options[$code] = $code;
562
+ }
563
+
564
+ return $options;
565
+ }
566
+
567
+ /**
568
+ *
569
+ * @param type $requestType
570
+ * @param type $id
571
+ * @param type $entityGlobalType
572
+ * @return array
573
+ */
574
+ public function changeStatus($requestType, $id, $entityGlobalType, $keyField) {
575
+
576
+ $result = array('status' => 1);
577
+
578
+ try {
579
+
580
+ $type = Mage::getModel('connector/content_types')
581
+ ->getTypeDetails($requestType);
582
+ $content_types_id = $type->getTypeId();
583
+
584
+ $itemModel = Mage::getModel('connector/translate_' . $entityGlobalType);
585
+
586
+ $itemsCollection = $itemModel->getCollection();
587
+ $itemsCollection->addFieldToFilter($keyField, $id)
588
+ ->addFieldToFilter('entity_type_id', $content_types_id);
589
+
590
+ if($itemsCollection->getSize()) {
591
+ $itemsCollection->getFirstItem()->delete();
592
+ $result['message'] = Mage::helper('connector')
593
+ ->__('Item was dettached successfully');
594
+ } else {
595
+ $dataToSave = array($keyField => $id,
596
+ 'entity_type_id' => $content_types_id);
597
+ $itemModel->setData($dataToSave)->save();
598
+
599
+ $result['message'] = Mage::helper('connector')
600
+ ->__('Data has saved successfully');
601
+ }
602
+ } catch (Mage_Core_Exception $e) {
603
+ $result['message'] = Mage::helper('connector')
604
+ ->__('Application internal error. Please see smartling log for details');
605
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
606
+ $result['error'] = $e->getMessage();
607
+ $result['status'] = 0;
608
+ }
609
+
610
+ return $result;
611
+ }
612
+
613
+ }
app/code/community/Smartling/Connector/Model/Content.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ * status completed
14
+ */
15
+ const CONTENT_STATUS_COMPLETED = 'completed';
16
+
17
+ /**
18
+ * status in progress
19
+ */
20
+ const CONTENT_STATUS_PROCESS = 'in progress';
21
+
22
+ /**
23
+ * status new
24
+ */
25
+ const CONTENT_STATUS_NEW = 'new';
26
+
27
+ /**
28
+ * set resource model
29
+ *
30
+ */
31
+ protected function _construct() {
32
+ $this->_init('connector/content');
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @return string
38
+ */
39
+ public function getContentModelClass(){
40
+ $type = $this->getType();
41
+ $typesModel = Mage::getModel('connector/content_types')->load($type);
42
+ if (!$typesModel->getId()){
43
+ Mage::getSingleton('admin/session')->addError(
44
+ Mage::helper('connector')->__("Content Type does not exists")
45
+ );
46
+ return;
47
+ }
48
+ return $typesModel->getModel();
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @param int | null $contentTypeId
54
+ * @return Smartling_Connector_Model_Resource_Content_Collection
55
+ */
56
+ public function getAddedItems($contentTypeId = null){
57
+ $collection = $this->getCollection()->addFieldToSelect('origin_content_id');
58
+
59
+ if (!is_null($contentTypeId)){
60
+ $collection->addFieldToFilter('type', array('eq' => (int) $contentTypeId));
61
+ }
62
+
63
+ $collection->getSelect()->group('origin_content_id');
64
+ return $collection;
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @return Smartling_Connector_Model_Resource_Content_Collection
70
+ */
71
+ public function getNewItems($project_id = 0, $content_id = 0){
72
+ $status = Smartling_Connector_Model_Content::CONTENT_STATUS_NEW;
73
+ $resource = Mage::getSingleton('core/resource');
74
+ $collection = $this->getCollection()
75
+ ->addFieldToFilter('status', array('eq' => $status));
76
+
77
+ if($project_id) {
78
+ $collection->addFieldToFilter('project_id', array('eq' => $project_id));
79
+ }
80
+
81
+ if($content_id) {
82
+ $collection->addFieldToFilter('content_id', array('eq' => $content_id));
83
+ }
84
+
85
+ $collection->getSelect()
86
+ ->reset(Zend_Db_Select::COLUMNS)
87
+ ->columns(array('content_id', 'type', 'origin_content_id', 'store_id', 'source_store_id', 'filename', 'project_id'))
88
+ ->joinLeft(array('t' => $resource->getTableName('connector/content_types')),
89
+ 'main_table.type = t.type_id',
90
+ array('model'))
91
+ ->joinInner(array('p' => $resource->getTableName('connector/projects')),
92
+ 'main_table.project_id = p.id',
93
+ array('project_code' => 'project_id', 'api_key' => 'key', 'retrieval_type')
94
+ )
95
+ ->joinInner(array('pl' => $resource->getTableName('connector/projects_locales')),
96
+ 'main_table.project_id = pl.parent_id and main_table.store_id = pl.store_id',
97
+ array(
98
+ 'locales' => new Zend_Db_Expr('GROUP_CONCAT(DISTINCT pl.locale_code SEPARATOR ",")')
99
+ ))
100
+ ->group('main_table.project_id')
101
+ ->group('main_table.origin_content_id');
102
+
103
+
104
+ return $collection;
105
+ }
106
+
107
+
108
+ /**
109
+ * Collection items which must be downloaded in singledownload Action
110
+ *
111
+ * @param int $contentId
112
+ * @param int $contentType
113
+ * @return Smartling_Connector_Model_Resource_Content_Collection
114
+ */
115
+ public function prepareDownloadItems($contentId, $contentType) {
116
+ $collection = $this->getCollection()
117
+ ->addFieldToFilter('origin_content_id', array('eq' => (int) $contentId))
118
+ ->addFieldToFilter('type', array('eq' => (int) $contentType))
119
+ ->addFieldToFilter('status', array('neq' => self::CONTENT_STATUS_NEW));
120
+ return $collection;
121
+ }
122
+
123
+ /**
124
+ *
125
+ * @param int $origin_content_id
126
+ * @param int $project_id
127
+ * @param int $store_id
128
+ * @return Smartling_Connector_Model_Resource_Content_Collection
129
+ */
130
+ public function getCollectionByUniqueKeys($origin_content_id, $project_id, $store_id) {
131
+ $collection = $this->getCollection()
132
+ ->addFieldTofilter('project_id', array('eq' => $project_id))
133
+ ->addFieldTofilter('origin_content_id', array('eq' => $origin_content_id))
134
+ ->addFieldTofilter('store_id', array('eq' => $store_id));
135
+ return $collection;
136
+ }
137
+
138
+ /**
139
+ * Item is ready wnen return empty array
140
+ * @return array
141
+ */
142
+ public function checkReadyForDownload($status, $locale_name) {
143
+ $errors = array();
144
+
145
+ if($status == Smartling_Connector_Model_Content::CONTENT_STATUS_NEW) {
146
+ $errors[] = Mage::helper('connector')->__("Sorry, the entity hasn't being translated yet. Locale [%s]", $locale_name);
147
+ } elseif($status == Smartling_Connector_Model_Content::CONTENT_STATUS_COMPLETED) {
148
+ $errors[] = Mage::helper('connector')->__("Sorry, the entity hasn already translated and applied. Locale [%s]", $locale_name);
149
+ }
150
+
151
+ return $errors;
152
+ }
153
+ }
app/code/community/Smartling/Connector/Model/Content/Abstract.php ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Abstract
5
+ *
6
+ * @author Smartling
7
+ */
8
+ abstract class Smartling_Connector_Model_Content_Abstract
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var string
15
+ */
16
+ protected $_entityType;
17
+
18
+ /**
19
+ *
20
+ * @var string
21
+ */
22
+ protected $_fileTypeModel;
23
+
24
+ /**
25
+ *
26
+ * @var string
27
+ */
28
+ protected $_title = '';
29
+
30
+ /**
31
+ *
32
+ * @var string
33
+ */
34
+ protected $_fileUri;
35
+
36
+ public function __construct() {
37
+ $this->_fileTypeModel = 'connector/types_xml';
38
+ }
39
+
40
+ abstract public function saveNames();
41
+
42
+ /**
43
+ *
44
+ * @return string|bool
45
+ */
46
+ public function getFileUri() {
47
+ if(strlen($this->_fileUri)) {
48
+ return $this->_fileUri . ".xml";
49
+ } else {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @param array $storeIds
57
+ * @return array
58
+ */
59
+ public function defineTranslateLocales($storeIds){
60
+ $locales = Mage::helper('connector')->getLocaleMap();
61
+ $translateLocales = array();
62
+ //$stores = (explode(",", $storeIds));
63
+ if (count($storeIds) > 1){
64
+ for ($i = 0; $i < count($storeIds); $i++){
65
+ $translateLocales[] = $locales[$storeIds[$i]];
66
+ }
67
+ } else {
68
+ $translateLocales[] = $locales[$storeIds[0]];
69
+ }
70
+ return $translateLocales;
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @return string
76
+ */
77
+ public function getBaseFileDir(){
78
+ return $this->_baseFileDir;
79
+ }
80
+
81
+ /**
82
+ *
83
+ * @return Mage_Adminhtml_Model_Session
84
+ */
85
+ protected function _getAdminSession(){
86
+ return Mage::getSingleton('adminhtml/session');
87
+ }
88
+
89
+ /**
90
+ * Return parsed response
91
+ *
92
+ * @param string $translatedContent
93
+ * @return array
94
+ */
95
+ public function getTranslatedContent($translatedContent) {
96
+ $content = Mage::getModel($this->_fileTypeModel);
97
+ return $content->loadContent($translatedContent)->getAllData();
98
+ }
99
+
100
+ /**
101
+ * Return parsed response for attributes options
102
+ *
103
+ * @param string $translatedContent
104
+ * @return array
105
+ */
106
+ public function getTranslatedAttributesOptions($translatedContent) {
107
+ $content = Mage::getModel($this->_fileTypeModel);
108
+ return $content->loadContent($translatedContent)->getOptionsValues();
109
+ }
110
+
111
+ /**
112
+ *
113
+ * @param int $entityType
114
+ * @param array $exclude
115
+ * @return null | array
116
+ */
117
+ protected function _getAttributes($entityType, array $exclude){
118
+ $trnaslateAttribs = array();
119
+ $attrCollection = Mage::helper('connector')
120
+ ->getAttributesForTranslation($entityType, $exclude);
121
+ if ($attrCollection->getSize() < 1){
122
+ return null;
123
+ }
124
+
125
+ foreach ($attrCollection as $_attribute){
126
+ if ($_attribute->getData('is_html_allowed_on_front') == 1){
127
+ $trnaslateAttribs['htmlcontent'][] = $_attribute->getAttributeCode();
128
+ } else {
129
+ $trnaslateAttribs['content'][] = $_attribute->getAttributeCode();
130
+ }
131
+ }
132
+ return $trnaslateAttribs;
133
+ }
134
+
135
+ /**
136
+ *
137
+ * @param Mage_Core_Model_Resource_Db_Collection_Abstract $attrCollection
138
+ * @return array
139
+ */
140
+ protected function formatAttributes(Mage_Core_Model_Resource_Db_Collection_Abstract $attrCollection) {
141
+
142
+ $translateAttributes = array();
143
+
144
+ if (!$attrCollection->getSize()){
145
+ return array();
146
+ }
147
+
148
+ foreach ($attrCollection as $_attribute) {
149
+ $areaKey = ($_attribute->getData('is_html_allowed_on_front') == 1)?'htmlcontent':'content';
150
+ $translateAttributes[$areaKey][] = array('attribute' => $_attribute->getAttributeCode(),
151
+ 'type' => $_attribute->getFrontendInput());
152
+ }
153
+
154
+ return $translateAttributes;
155
+ }
156
+
157
+ /**
158
+ * Creates the same content for other locales
159
+ *
160
+ * @param array $translatedContent
161
+ * @param int $originContentId
162
+ * @param int $storeId
163
+ * @param Smartling_Connector_Model_Content $contentModel
164
+ * @return boolean|Mage_Core_Model_Abstract
165
+ */
166
+ public function createDynamicContent($translatedContent, $originContentId, $storeId) {
167
+ $contentTypeEntity = $this->getContentTypeEntityModel();
168
+ $contentTypeEntity->setStoreId($storeId); // set store in origData
169
+ $contentTypeEntity->load($originContentId);
170
+ if (!$contentTypeEntity->getId()){
171
+ return false;
172
+ }
173
+
174
+ $errors = '';
175
+
176
+ if($contentTypeEntity instanceof Mage_Catalog_Model_Category) {
177
+ $this->setDefaultAttributesValues($contentTypeEntity, $translatedContent);
178
+ }
179
+
180
+ foreach ($translatedContent as $attribute => $value) {
181
+ $contentTypeEntity->setData($attribute, $value);
182
+ }
183
+
184
+ $contentTypeEntity->setStoreId($storeId);
185
+ $contentTypeEntity->setWebsiteIds(array( Mage::app()->getStore($storeId)->getWebsite()->getId() ));
186
+
187
+ try {
188
+ $contentTypeEntity->save();
189
+ } catch (Exception $e){
190
+ Mage::getSingleton('adminhtml/session')->addError(
191
+ Mage::helper('connector')->__($e->getMessage())
192
+ );
193
+ $errors = $e->getMessage();
194
+ }
195
+
196
+ if ($errors) {
197
+ Mage::helper('connector')->log($errors, Zend_log::ERR);
198
+ return false;
199
+ }
200
+
201
+ return $contentTypeEntity;
202
+ }
203
+
204
+ /**
205
+ * Check default value usage fact
206
+ *
207
+ * @param Mage_Eav_Model_Entity_Attribute $dataObject
208
+ * @param mixed $attributeModel
209
+ * @return boolean
210
+ */
211
+ protected function usedDefault($dataObject, $attributeModel)
212
+ {
213
+
214
+ $attributeCode = $attributeModel->getAttributeCode();
215
+ $value = $dataObject->getData($attributeCode);
216
+
217
+ $defaultValue = $dataObject->getAttributeDefaultValue($attributeCode);
218
+
219
+ if (!$dataObject->getExistsStoreValueFlag($attributeCode)) {
220
+ return true;
221
+ } else if ($value == $defaultValue &&
222
+ $dataObject->getStoreId() != Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID
223
+ ) {
224
+ return false;
225
+ }
226
+ if ($defaultValue === false && !$attributeModel->getIsRequired() && $value) {
227
+ return false;
228
+ }
229
+ return $defaultValue === false;
230
+ }
231
+
232
+ /**
233
+ * Overwrite 'use default value' checkbox is nesesary
234
+ * @param Mage_Catalog_Model_Abstract $contentTypeEntity
235
+ * @param array $translatedContent
236
+ */
237
+ protected function setDefaultAttributesValues($contentTypeEntity, $translatedContent) {
238
+
239
+ $attributeCodes = array_keys($contentTypeEntity->getData());
240
+ foreach ($attributeCodes as $attributeCode) {
241
+ $attributeModel = Mage::getModel('eav/entity_attribute')->loadByCode($this->_entityType, $attributeCode);
242
+
243
+ $isGlobalPriceScope = false;
244
+
245
+ if ($attributeCode == 'price') {
246
+ $priceScope = Mage::getStoreConfig('catalog/price/scope');
247
+ if ($priceScope == 0) {
248
+ $isGlobalPriceScope = true;
249
+ }
250
+ }
251
+
252
+ if(!sizeof($attributeModel->getData()) ||
253
+ $attributeModel->getData('is_global') == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL ||
254
+ $isGlobalPriceScope
255
+ ) {
256
+ continue;
257
+ }
258
+
259
+ $usedDefault = $this->usedDefault($contentTypeEntity, $attributeModel);
260
+
261
+ // check if default value uses and translated content is not empty
262
+ if($usedDefault && !array_key_exists($attributeModel->getAttributeCode(), $translatedContent)) {
263
+ $contentTypeEntity->setData($attributeCode, false);
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * define entity type Id by entity code
270
+ *
271
+ * @return bool | int
272
+ */
273
+ public function getEntityTypeId(){
274
+ $entityType = Mage::getModel('eav/entity_type')->loadByCode($this->_entityType);
275
+ if (!$entityType->getId()){
276
+ Mage::helper('connector')
277
+ ->log("Entity type " . $this->_entityType . " undefined", Zend_log::ERR);
278
+ return false;
279
+ }
280
+ return $entityType->getId();
281
+ }
282
+
283
+ /**
284
+ * Used to define content title while adding new content for translation
285
+ * Holds in smartling content table
286
+ *
287
+ * @return string
288
+ */
289
+ public function getContentTitle() {
290
+ return $this->_title;
291
+ }
292
+
293
+ /**
294
+ *
295
+ * @param string $filename
296
+ * @param int $item_id
297
+ * @param int $project_id
298
+ * @return string
299
+ */
300
+ public function formatFileUri($filename, $item_id, $project_id) {
301
+ $fileUri = $filename . "_" . $item_id . '_project-' . $project_id;
302
+ return $fileUri;
303
+ }
304
+
305
+ /**
306
+ * Fill empty title name fields
307
+ * @return boolean
308
+ */
309
+ protected function saveEavNames() {
310
+
311
+ try {
312
+ $resource = Mage::getSingleton('core/resource');
313
+ $_adapter = $resource->getConnection('core_write');
314
+
315
+ $adminStoreId = Mage_Core_Model_App::ADMIN_STORE_ID;
316
+
317
+ $model = $this->getContentTypeEntityModel();
318
+
319
+ $entity = $model->getResource();
320
+
321
+ $entityTableName = $resource->getTableName($model->getResourceName());
322
+
323
+ $attribute = Mage::getSingleton('eav/config')->getCollectionAttribute($entity->getType(), 'name');
324
+ $attributeId = $attribute->getId();
325
+ $backendTableName = $attribute->getBackendTable();
326
+
327
+ $contentTableName = $resource->getTableName('connector/translate_content');
328
+
329
+ $updateNamesQuery = "UPDATE {$contentTableName} c "
330
+ . " JOIN {$entityTableName} AS `e` ON c.origin_content_id = e.entity_id "
331
+ . " AND c.content_title = '' "
332
+ . " JOIN {$backendTableName} AS `at_name` ON "
333
+ . " (`at_name`.`entity_id` = `e`.`entity_id`) "
334
+ . " AND (`at_name`.`attribute_id` = '{$attributeId}') "
335
+ . " AND (`at_name`.`store_id` = {$adminStoreId})
336
+ SET c.content_title = at_name.value";
337
+
338
+ $_adapter->query($updateNamesQuery);
339
+ } catch (Exception $ex) {
340
+ Mage::helper('connector')->log("Current entity names (EAV Model) weren't updated: " . $ex->getMessage(), Zend_log::ERR);
341
+ return false;
342
+ }
343
+
344
+ return true;
345
+ }
346
+
347
+ /**
348
+ * Fill empty title name fields
349
+ * @param string $tableStoreNameKey
350
+ * @param string $titleFiledName
351
+ * @return boolean
352
+ */
353
+ protected function saveFlatNames($tableStoreNameKey, $titleFiledName = 'title') {
354
+
355
+ try {
356
+ $resource = Mage::getSingleton('core/resource');
357
+ $_adapter = $resource->getConnection('core_write');
358
+
359
+ $model = $this->getContentTypeEntityModel();
360
+
361
+ $entityTableName = $resource->getTableName($model->getResourceName());
362
+ $IdFieldName = $model->getIdFieldName();
363
+
364
+ $contentTableName = $resource->getTableName('connector/translate_content');
365
+ $entityStoreTableName = $resource->getTableName($tableStoreNameKey);
366
+
367
+ $updateNamesQuery = $this->getFlatNamesQuery($contentTableName, $entityTableName, $entityStoreTableName, $IdFieldName, $titleFiledName, 'c.source_store_id');
368
+ $_adapter->query($updateNamesQuery);
369
+
370
+ $updateNamesQueryDefaultStoreGrouped = $this->getFlatNamesQueryGrouped($contentTableName, $entityTableName, $entityStoreTableName, $IdFieldName, $titleFiledName);
371
+ $_adapter->query($updateNamesQueryDefaultStoreGrouped);
372
+
373
+ $updateNamesQueryDefaultStore = $this->getFlatNamesQuery($contentTableName, $entityTableName, $entityStoreTableName, $IdFieldName, $titleFiledName);
374
+ $_adapter->query($updateNamesQueryDefaultStore);
375
+
376
+ } catch (Exception $ex) {
377
+ Mage::helper('connector')->log("Current entity names (Flat Model) weren't updated: " . $ex->getMessage(), Zend_log::ERR);
378
+ return false;
379
+ }
380
+
381
+ return true;
382
+ }
383
+
384
+ /**
385
+ * Get query template to update title at flat table
386
+ * @param type $contentTableName
387
+ * @param type $entityTableName
388
+ * @param type $IdFieldName
389
+ * @param type $titleFiledName
390
+ * @param type $sourceStoreField
391
+ */
392
+ private function getFlatNamesQuery($contentTableName, $entityTableName, $entityStoreTableName, $IdFieldName, $titleFiledName, $sourceStoreField = 0) {
393
+
394
+ $updateNamesQuery = "UPDATE {$contentTableName} c "
395
+ . " JOIN {$entityTableName} AS `e` ON c.content_title = '' "
396
+ . " AND c.origin_content_id = e." . $IdFieldName . " "
397
+ . " JOIN {$entityStoreTableName} AS `e2s` ON "
398
+ . " (`e2s`.`{$IdFieldName}` = `e`.`{$IdFieldName}`) "
399
+ . " AND (`e2s`.`store_id` = {$sourceStoreField})"
400
+ . " SET c.content_title = e.`{$titleFiledName}`";
401
+ return $updateNamesQuery;
402
+ }
403
+
404
+ /**
405
+ * Get query template to update title at flat table. Query is cross content store view and default store group
406
+ * @param type $contentTableName
407
+ * @param type $entityTableName
408
+ * @param type $IdFieldName
409
+ * @param type $titleFiledName
410
+ */
411
+ private function getFlatNamesQueryGrouped($contentTableName, $entityTableName, $entityStoreTableName, $IdFieldName, $titleFiledName) {
412
+
413
+ $updateNamesQuery = "UPDATE {$contentTableName} c "
414
+ . " JOIN {$entityTableName} AS `e` ON c.content_title = '' "
415
+ . " AND c.origin_content_id = e." . $IdFieldName . " "
416
+ . " JOIN {$entityStoreTableName} AS `e2s` ON "
417
+ . " (`e2s`.`{$IdFieldName}` = `e`.`{$IdFieldName}`) "
418
+ . "JOIN core_store_group cs ON cs.default_store_id = e2s.store_id "
419
+ . "AND `e2s`.`store_id` = cs.default_store_id"
420
+ . " SET c.content_title = e.`{$titleFiledName}`";
421
+ return $updateNamesQuery;
422
+ }
423
+
424
+ //
425
+
426
+ /**
427
+ * Retrieve stores collection with default store
428
+ *
429
+ * @return Mage_Core_Model_Mysql4_Store_Collection
430
+ */
431
+ public function getStores()
432
+ {
433
+ $stores = $this->getData('stores');
434
+ if (is_null($stores)) {
435
+ $stores = Mage::getModel('core/store')
436
+ ->getResourceCollection()
437
+ ->setLoadDefault(true)
438
+ ->load();
439
+ $this->setData('stores', $stores);
440
+ }
441
+ return $stores;
442
+ }
443
+
444
+ /**
445
+ *
446
+ * @param string $content
447
+ * @param string $fileUri
448
+ * @param array $item
449
+ * @return bool
450
+ */
451
+ public function uploadContent($content, $fileUri, $item) {
452
+
453
+ /** @var $translator Smartling_Connector_Model_Translator */
454
+ $translator = Mage::getModel('connector/translator',
455
+ array('apiKey' => $item['api_key'],
456
+ 'projectId' => $item['project_code'],
457
+ 'project_id' => $item['project_id'],
458
+ 'locales' => $item['locales']
459
+ )
460
+ );
461
+ $translator->setFileType(Smartling_Connector_Model_Translator::FILE_TYPE_XML);
462
+
463
+ $response = $translator->uploadTranslateContent($content, $fileUri);
464
+
465
+ Mage::helper('connector')->log($response, Zend_log::INFO);
466
+
467
+ return $translator->isSuccessResponse($response);
468
+ }
469
+
470
+ /**
471
+ * Get system directory path
472
+ *
473
+ * @return boolean
474
+ */
475
+ public function getSystemDirectoryPath() {
476
+ return Mage::getBaseDir('var') . '/smartling/localization_files';
477
+ }
478
+
479
+
480
+
481
+ }
app/code/community/Smartling/Connector/Model/Content/Attribute.php ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Attibute
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Attribute
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface
11
+ {
12
+
13
+ const CONTENT_TYPE = 'attribute';
14
+
15
+ /**
16
+ * define entity type
17
+ *
18
+ * @var string
19
+ */
20
+ protected $_entityType = 'catalog_attribute';
21
+
22
+ /**
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_fileTypeModel;
27
+
28
+ /**
29
+ *
30
+ * @var string
31
+ */
32
+ protected $_fileUri;
33
+
34
+ /**
35
+ * Magento entity type ID
36
+ * @var int
37
+ */
38
+ protected $_entityTypeId;
39
+
40
+ /**
41
+ * Define attributes registry key prefix
42
+ *
43
+ * @var string
44
+ */
45
+ protected $_attributesRegistryPrefix = 'eav_attributes_';
46
+
47
+ public function __construct() {
48
+ parent::__construct();
49
+ $this->_fileTypeModel = 'connector/types_general';
50
+ $this->_entityTypeId = Mage::getModel('eav/entity')->setType(Mage_Catalog_Model_Product::ENTITY)->getTypeId();
51
+ }
52
+
53
+ /**
54
+ * Creates the same content for other locales
55
+ *
56
+ * @param array $translatedContent
57
+ * @param int $id
58
+ * @param array $storeId
59
+ * @param Smartling_Connector_Model_Content $contentModel
60
+ */
61
+ public function createContent($data, $id, $storeId){
62
+
63
+ if ($data) {
64
+ /** @var $session Mage_Admin_Model_Session */
65
+ $session = Mage::getSingleton('adminhtml/session');
66
+ /* @var $model Mage_Catalog_Model_Entity_Attribute */
67
+ $model = Mage::getModel('catalog/resource_eav_attribute');
68
+ /* @var $helper Mage_Catalog_Helper_Product */
69
+ $helper = Mage::helper('catalog/product');
70
+
71
+ if ($id) {
72
+ $model->load($id);
73
+
74
+ if (!$model->getId()) {
75
+ $session->addError(
76
+ Mage::helper('catalog')->__('This Attribute no longer exists'));
77
+ return false;
78
+ }
79
+
80
+ // entity type check
81
+ if ($model->getEntityTypeId() != $this->_entityTypeId) {
82
+ $session->addError(
83
+ Mage::helper('catalog')->__('This attribute cannot be updated.'));
84
+ $session->setAttributeData($data);
85
+ return false;
86
+ }
87
+
88
+ $data['attribute_code'] = $model->getAttributeCode();
89
+ $data['is_user_defined'] = $model->getIsUserDefined();
90
+ $data['frontend_input'] = $model->getFrontendInput();
91
+ } else {
92
+ $data['source_model'] = $helper->getAttributeSourceModelByInputType($data['frontend_input']);
93
+ $data['backend_model'] = $helper->getAttributeBackendModelByInputType($data['frontend_input']);
94
+ }
95
+
96
+ if (!isset($data['is_configurable'])) {
97
+ $data['is_configurable'] = 0;
98
+ }
99
+ if (!isset($data['is_filterable'])) {
100
+ $data['is_filterable'] = 0;
101
+ }
102
+ if (!isset($data['is_filterable_in_search'])) {
103
+ $data['is_filterable_in_search'] = 0;
104
+ }
105
+
106
+ if (is_null($model->getIsUserDefined()) || $model->getIsUserDefined() != 0) {
107
+ $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']);
108
+ }
109
+
110
+ $defaultValueField = $model->getDefaultValueByInput($data['frontend_input']);
111
+
112
+ if(!isset($data['apply_to'])) {
113
+ $data['apply_to'] = array();
114
+ }
115
+
116
+ // Add data to options for all stores
117
+ $this->parseData($model, $data, $storeId);
118
+
119
+ $model->addData($data);
120
+
121
+ try {
122
+ $model->save();
123
+ $session->addSuccess(
124
+ Mage::helper('catalog')->__('The attribute has been saved.'));
125
+
126
+ /**
127
+ * Clear translation cache because attribute labels are stored in translation
128
+ */
129
+ Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
130
+ $session->setAttributeData(false);
131
+ return true;
132
+ } catch (Exception $e) {
133
+ $session->addError($e->getMessage());
134
+ $session->setAttributeData($data);
135
+ return false;
136
+ }
137
+ } else {
138
+ $errorMessage = Mage::helper('connector')->__('Attribute data has not been specified.');
139
+ $session->addError($errorMessage);
140
+ return false;
141
+ }
142
+
143
+ }
144
+
145
+ /**
146
+ * Parse received data and merge with original one
147
+ *
148
+ * @param Mage_Catalog_Model_Resource_Eav_Attribute $model
149
+ * @param array $data The data received from smartling
150
+ * @param type $destinationStoreId
151
+ * @return boolean
152
+ */
153
+ protected function parseData(Mage_Catalog_Model_Resource_Eav_Attribute $model, &$data, $destinationStoreId) {
154
+
155
+ /** @var $helperCatalog Mage_Catalog_Helper_Data */
156
+ $helperCatalog = Mage::helper('catalog');
157
+
158
+ $exist_data = $model->getData();
159
+
160
+ // Attribute labels
161
+ foreach ($data['frontend_label'] as & $value) {
162
+ if ($value) {
163
+ $value = $helperCatalog->stripTags($value);
164
+ }
165
+ }
166
+
167
+ // Merge original and received data
168
+ $data = array_replace_recursive($exist_data, $data);
169
+
170
+ $data['default'] = array();
171
+
172
+ if(isset($exist_data['default_value']) && strlen($exist_data['default_value'])) {
173
+ $data['default'] = explode(',', $exist_data['default_value']);
174
+ }
175
+
176
+ if(is_null($model->getSource())) {
177
+ return true;
178
+ }
179
+
180
+ // Parse attributes options
181
+ Mage::helper('connector')->mergeAttributesOptions($model, $data, $destinationStoreId);
182
+
183
+ return true;
184
+ }
185
+
186
+ /**
187
+ * Creates xml content for translation
188
+ * Also defines filename uri for upload content to Smartling via API
189
+ * Defines content title for smartling translation table
190
+ *
191
+ * @param Mage_Catalog_Model_Resource_Attribute|int $attribute
192
+ * @param int $project_id Profile ID
193
+ * @param int $sourceStoreId Source locale
194
+ * @return string
195
+ */
196
+ public function createTranslateContent($attribute, $project_id, $sourceStoreId) {
197
+
198
+ if (is_numeric($attribute)) {
199
+ $attribute = $this->getContentTypeEntityModel()
200
+ ->setStoreId($sourceStoreId)
201
+ ->load($attribute);
202
+ }
203
+
204
+ $label = $attribute->getStoreLabel();
205
+
206
+ $optionsAttributeHead = array('attribute' => 'frontend_label',
207
+ 'type' => 'text');
208
+
209
+ $content = Mage::getModel($this->_fileTypeModel);
210
+ $content->setContentGroupAttribute(array('attribute_id' => $attribute->getId()));
211
+ $content->setContent($label, $optionsAttributeHead, 'htmlcontent');
212
+
213
+ if ($attribute->usesSource()) {
214
+
215
+ $optionsAttributeOptionsHead = array('attribute' => 'options_values',
216
+ 'type' => $attribute->getFrontendInput());
217
+
218
+ $contentValue = array();
219
+ $options = $attribute->getSource()->getAllOptions(false);
220
+
221
+ if(is_array($options)) {
222
+ foreach($options as $option) {
223
+ $contentValue[$option['value']] = $option['label'];
224
+ }
225
+ } else {
226
+ Mage::helper('connector')->log(
227
+ Mage::helper('connector')
228
+ ->__('%s attribute options is not an array',
229
+ $attribute->getAttributeCode()),
230
+ Zend_Log::DEBUG);
231
+ }
232
+
233
+ if(sizeof($contentValue)) {
234
+ switch ($attribute->getFrontendInput()) {
235
+ case 'select':
236
+ case 'multiselect':
237
+ $content->setContent($contentValue, $optionsAttributeOptionsHead, 'list');
238
+ break;
239
+ default:
240
+ Mage::helper('connector')->log(
241
+ Mage::helper('connector')
242
+ ->__('%s attribute has unexpected type. multiselect and select supported. %s received',
243
+ $attribute->getAttributeCode(),
244
+ $attribute->getFrontendInput()),
245
+ Zend_Log::DEBUG);
246
+ break;
247
+ }
248
+ }
249
+ }
250
+
251
+ //create full xml content for Api
252
+ $translateContent = $content->createContentFile();
253
+
254
+ $filename = ($attribute->getAttributeCode()) ? $attribute->getAttributeCode() . "_attribute_id" : 'attribute';
255
+
256
+ $this->_fileUri = $this->formatFileUri($filename, $attribute->getId(), $project_id);
257
+ $this->_title = $label;
258
+
259
+ return $translateContent;
260
+
261
+ }
262
+
263
+ /**
264
+ *
265
+ * @return Mage_Catalog_Model_Resource_Eav_Attribute
266
+ */
267
+ public function getContentTypeEntityModel() {
268
+ return Mage::getModel('catalog/resource_eav_attribute');
269
+ }
270
+
271
+ /**
272
+ *
273
+ * @return string
274
+ */
275
+ public function getContentTypeCode(){
276
+ return static::CONTENT_TYPE;
277
+ }
278
+
279
+ /**
280
+ *
281
+ * @return boolean
282
+ */
283
+ public function saveNames() {
284
+
285
+ try {
286
+ $resource = Mage::getSingleton('core/resource');
287
+ $_adapter = $resource->getConnection('write');
288
+
289
+ $entityTableName = $resource->getTableName('eav_attribute');
290
+
291
+ $contentTableName = $resource->getTableName('connector/translate_content');
292
+
293
+ $updateNamesQuery = "UPDATE {$contentTableName} c "
294
+ . " JOIN {$entityTableName} AS `e` ON c.content_title = '' "
295
+ . " AND c.origin_content_id = e.attribute_id "
296
+ . " SET c.content_title = e.frontend_label";
297
+
298
+ $_adapter->query($updateNamesQuery);
299
+ } catch (Exception $ex) {
300
+ Mage::helper('connector')->log("Attributes names weren't updated: " . $ex->getMessage(), Zend_log::ERR);
301
+ return false;
302
+ }
303
+
304
+ return true;
305
+ }
306
+
307
+ /**
308
+ * Return parsed response
309
+ *
310
+ * @param string $translatedContent
311
+ * @return array
312
+ */
313
+ public function getTranslatedContent($translatedContent) {
314
+ $content = Mage::getModel($this->_fileTypeModel);
315
+ $attributeData = $content->loadContent($translatedContent)->getAllData();
316
+
317
+ $optionsValues = $content->loadContent($translatedContent)->getOptionsValues();
318
+ if(sizeof($optionsValues)) {
319
+ $attributeData['option'] = $optionsValues;
320
+ }
321
+
322
+ return $attributeData;
323
+ }
324
+ }
app/code/community/Smartling/Connector/Model/Content/Attributes/Builder.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Model_Content_Attributes_Builder
4
+ extends Varien_Object
5
+ {
6
+ /**
7
+ *
8
+ * @var array
9
+ */
10
+ protected $_params = array();
11
+
12
+
13
+ /**
14
+ *
15
+ * @var array
16
+ */
17
+ protected $_defaultStoreId = array();
18
+
19
+
20
+
21
+ public function __construct() {
22
+ $this->_params = array(
23
+ 'option_id' => 0,
24
+ 'store_id' => $this->_defaultStoreId,
25
+ 'value' => 0
26
+ );
27
+ }
28
+
29
+ public function setOptionId($value) {
30
+ $this->_params['option_id'] = $value;
31
+ return $this;
32
+ }
33
+
34
+ public function setStoreId($value) {
35
+ $this->_params['store_id'] = $value;
36
+ return $this;
37
+ }
38
+
39
+ public function setValue($value) {
40
+ $this->_params['value'] = $value;
41
+ return $this;
42
+ }
43
+
44
+ /**
45
+ * Return all parameters
46
+ *
47
+ * @return array
48
+ */
49
+ public function buildParameters() {
50
+ return $this->_params;
51
+ }
52
+ }
app/code/community/Smartling/Connector/Model/Content/Attributes/Options.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Abstract
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Attributes_Options
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ *
14
+ * List of values for import
15
+ * @var array
16
+ */
17
+ protected $_list;
18
+
19
+ /**
20
+ * Add unique param to array
21
+ * @param array $params
22
+ */
23
+ public function add(array $params) {
24
+ $this->_list[$params['option_id']][$params['store_id']] = $params;
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @return boolean
30
+ */
31
+ public function run() {
32
+
33
+ if(!sizeof($this->_list)) {
34
+ return false;
35
+ }
36
+
37
+ $incUpdated = 0;
38
+
39
+ $resource = Mage::getModel('core/resource');
40
+ $adapter = $resource->getConnection('core_write');
41
+
42
+ $attributeOptionTable = $resource->getTableName('eav_attribute_option_value');
43
+
44
+ foreach ($this->_list as $storeParams) {
45
+ foreach ($storeParams as $params) {
46
+ $query = "SELECT count(*) as total FROM " . $attributeOptionTable . " WHERE option_id = :option_id AND store_id = :store_id and value = :value";
47
+ $binds = array(
48
+ 'option_id' => $params['option_id'],
49
+ 'store_id' => $params['store_id'],
50
+ 'value' => $params['value']
51
+ );
52
+
53
+ $total = $adapter->fetchOne($query, $binds);
54
+ if(!$total) {
55
+ $adapter->insertMultiple($attributeOptionTable, $binds);
56
+ $incUpdated++;
57
+ }
58
+ }
59
+ }
60
+
61
+ if($incUpdated) {
62
+ Mage::helper('connector')->log("{$incUpdated} eav attribute option values have been updated", Zend_log::INFO);
63
+ }
64
+
65
+ return (boolean)$incUpdated;
66
+ }
67
+
68
+ }
app/code/community/Smartling/Connector/Model/Content/Category.php ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Category
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Category
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface,
11
+ Smartling_Connector_Model_Content_EavEntityInterface
12
+ {
13
+
14
+ const CONTENT_TYPE = 'category';
15
+
16
+ /**
17
+ * define entity type
18
+ *
19
+ * @var string
20
+ */
21
+ protected $_entityType = 'catalog_category';
22
+
23
+ /**
24
+ * Smartling content types
25
+ *
26
+ * @var array
27
+ */
28
+ protected $_smartlingContentTypes = array('content', 'htmlcontent');
29
+
30
+ /**
31
+ *
32
+ * @var string
33
+ */
34
+ protected $_fileTypeModel;
35
+
36
+ /**
37
+ *
38
+ * @var string
39
+ */
40
+ protected $_baseFileDir;
41
+
42
+ /**
43
+ *
44
+ * @var string
45
+ */
46
+ protected $_fileUri;
47
+
48
+ /**
49
+ * Define attributes registry key prefix
50
+ *
51
+ * @var string
52
+ */
53
+ protected $_attributesRegistryPrefix = 'category_attributes_';
54
+
55
+ public function __construct() {
56
+ parent::__construct();
57
+ $this->_fileTypeModel = 'connector/types_general';
58
+ }
59
+
60
+ /**
61
+ * Creates the same content for other locales
62
+ *
63
+ * @param array $translatedContent
64
+ * @param int $originContentId
65
+ * @param array $storeId
66
+ * @param Smartling_Connector_Model_Content $contentModel
67
+ */
68
+ public function createContent($translatedContent, $originContentId, $storeId){
69
+ return parent::createDynamicContent($translatedContent, $originContentId, $storeId);
70
+ }
71
+
72
+ /**
73
+ * Creates xml content for translation
74
+ * Also defines filename uri for upload content to Smartling via API
75
+ * Defines content title for smartling translation table
76
+ *
77
+ * @param Mage_Catalog_Model_Category|int $category $category
78
+ * @param int $project_id Profile ID
79
+ * @param int $sourceStoreId Source locale
80
+ * @return string
81
+ */
82
+ public function createTranslateContent($category, $project_id, $sourceStoreId) {
83
+
84
+ if (is_numeric($category)) {
85
+ $category = $this->getContentTypeEntityModel()
86
+ ->setStoreId($sourceStoreId)
87
+ ->load($category);
88
+ }
89
+
90
+ $attributes = Mage::registry($this->_attributesRegistryPrefix);
91
+
92
+ if(!is_array($attributes)) {
93
+ $attributesCollection = $this->getAttributes();
94
+
95
+ if (!$attributesCollection->getSize()) {
96
+ $this->_getAdminSession()->addError(
97
+ Mage::helper('connector')->__("Attributes weren't selected")
98
+ );
99
+
100
+ Mage::helper('connector')->log("Category attributes weren't selected", Zend_log::ERR);
101
+ return '-1';
102
+ } else {
103
+ $attributes = $this->formatAttributes($attributesCollection);
104
+ Mage::register($this->_attributesRegistryPrefix, $attributes);
105
+ }
106
+ }
107
+
108
+
109
+
110
+ $content = Mage::getModel($this->_fileTypeModel);
111
+ $content->setContentGroupAttribute(array('category_id' => $category->getId()));
112
+
113
+ //create smartling type content
114
+ foreach ($this->_smartlingContentTypes as $type) {
115
+
116
+ if (!empty($attributes[$type])) {
117
+
118
+ $count = sizeof($attributes[$type]);
119
+ for ($i = 0; $i < $count; $i++) {
120
+ $decoratorType = $type;
121
+
122
+ $contentValue = $category->getData($attributes[$type][$i]['attribute']);
123
+
124
+ if ($contentValue){
125
+
126
+ switch ($attributes[$type][$i]['type']) {
127
+ case 'select':
128
+ $attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_category', $attributes[$type][$i]['attribute']);
129
+ $contentValueAttributes = $attribute->getSource()->getOptionText($category->getData($attributes[$type][$i]['attribute']));
130
+ $contentValue = array($contentValue => $contentValueAttributes);
131
+ break;
132
+ case 'multiselect':
133
+
134
+ $attributeIds = explode(',',$contentValue);
135
+
136
+ $contentValue = array();
137
+ foreach ($attributeIds as $attributeId) {
138
+ $attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_category', $attributes[$type][$i]['attribute']);
139
+ $contentValueAttributes = $attribute->getSource()->getOptionText($attributeId);
140
+ $contentValue[$attributeId] = $contentValueAttributes;
141
+ }
142
+ break;
143
+ default:
144
+ if($type != 'htmlcontent' && strlen($contentValue) != strlen(strip_tags($contentValue))) {
145
+ $decoratorType = 'htmlcontent';
146
+ }
147
+ break;
148
+ }
149
+
150
+ if(is_array($contentValue)) {
151
+ $decoratorType = 'list';
152
+ }
153
+
154
+ $content->setContent($contentValue, $attributes[$type][$i], $decoratorType);
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ //create full xml content for Api
161
+ $translateContent = $content->createContentFile();
162
+
163
+ $filename = ($category->getUrlKey()) ? $category->getUrlKey() . "_cat_id" : 'category';
164
+
165
+ $this->_fileUri = $this->formatFileUri($filename, $category->getId(), $project_id);
166
+ $this->_title = $category->getName();
167
+
168
+ return $translateContent;
169
+ }
170
+
171
+ /**
172
+ *
173
+ * @return \Mage_Catalog_Model_Resource_Category_Attribute_Collection
174
+ */
175
+ public function getAttributes() {
176
+
177
+ $resource = Mage::getModel('core/resource');
178
+ $systemAttributes = array_keys(Mage::getStoreConfig('connector/translate_attributes/catalog_category'));
179
+
180
+ $collection = Mage::getResourceModel('catalog/category_attribute_collection')
181
+ ->addFieldToFilter('is_global', Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE)
182
+ ->addFieldToFilter('attribute_code', array('nin' => $systemAttributes));
183
+
184
+ $collection->getSelect()
185
+ ->joinInner(
186
+ array('ia' => $resource->getTableName('connector/translate_attributes')),
187
+ 'ia.attribute_id = main_table.attribute_id', array()
188
+ );
189
+
190
+ return $collection;
191
+ }
192
+
193
+ /**
194
+ *
195
+ * @return Mage_Catalog_Model_Category
196
+ */
197
+ public function getContentTypeEntityModel(){
198
+ return Mage::getModel('catalog/category');
199
+ }
200
+
201
+ /**
202
+ *
203
+ * @return string
204
+ */
205
+ public function getContentTypeCode(){
206
+ return static::CONTENT_TYPE;
207
+ }
208
+
209
+ /**
210
+ * @deprecated since version 0.2.2
211
+ * @param int $content_id
212
+ * @return string
213
+ */
214
+ public function setContentTitle($content_id) {
215
+ $categoryModel = Mage::getModel('catalog/category')->load($content_id);
216
+ $this->_title = $categoryModel->getName();
217
+ }
218
+
219
+ /**
220
+ *
221
+ * @return boolean
222
+ */
223
+ public function saveNames() {
224
+ return parent::saveEavNames();
225
+ }
226
+ }
app/code/community/Smartling/Connector/Model/Content/Category/Observer.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Category_Observer
9
+ {
10
+
11
+ /**
12
+ * upload content for translation if translation enabled
13
+ *
14
+ * @param Varien_Event_Observer $object
15
+ */
16
+ public function sendCategoryContentToTranslator(Varien_Event_Observer $object){
17
+ $category = $object->getEvent()->getCategory();
18
+ if (is_array($category->getData('locales'))) {
19
+ $locales = $category->getData('locales');
20
+ $contentModel = Mage::getModel('connector/content_category');
21
+ $translator = Mage::getModel('connector/translator');
22
+
23
+ //create and save xml content for smartling translations
24
+ //$content = $contentModel->createTranslateContent($category);
25
+
26
+ $processData = array(
27
+ 'type' => Mage::helper('connector')
28
+ ->findTypeIdByTypeName(Smartling_Connector_Model_Content_Category::CONTENT_TYPE),
29
+ 'origin_content_id' => $category->getId(),
30
+ 'content_title' => $category->getName(),
31
+ );
32
+ for ($i = 0; $i < sizeof($locales); $i++) {
33
+ //$translator->uploadContent($contentModel, $locales[$i], $processData, $content);
34
+ $result = Mage::getResourceModel('connector/content')
35
+ ->addSingleItem($locales[$i], $processData);
36
+ if ($result && $result !== 0) {
37
+ $message = Mage::helper('connector')
38
+ ->__("New item added in translation queue for locale %s", $locales[$i]);
39
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
40
+ } elseif ($result == 0) {
41
+ $message = Mage::helper('connector')
42
+ ->__("Item already added in translation queue for locale %s", $locales[$i]);
43
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
44
+ } else {
45
+ $errors = "Unable to add Item to translation queue for locale {$locales[$i]}";
46
+ Mage::getSingleton('adminhtml/session')->addError($message);
47
+ }
48
+ }
49
+ // if ($content != ""){
50
+ // for ($i = 0; $i < sizeof ($locales); $i++) {
51
+ // $translator->uploadContent($contentModel, $locales[$i], $processData, $content);
52
+ // }
53
+ // } else {
54
+ // Mage::getSingleton('adminhtml/session')->addError(
55
+ // Mage::helper('connector')->__('Content does not exists')
56
+ // );
57
+ // }
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Add locales params to product for sending product content to Smartling
63
+ *
64
+ *
65
+ * @param Varien_Event_Observer $object
66
+ */
67
+ public function addTranslationOptions (Varien_Event_Observer $object) {
68
+ $request = $object->getEvent()->getRequest();
69
+ if ($locales = $request->getParam('locales')) {
70
+ $category = $object->getEvent()->getCategory();
71
+ $category->setData('locales', $locales);
72
+ }
73
+ }
74
+ }
app/code/community/Smartling/Connector/Model/Content/CmsBlock.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsBlock
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_CmsBlock
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface
11
+ {
12
+
13
+ const CONTENT_TYPE = 'cmsBlock';
14
+
15
+ /**
16
+ *
17
+ * @var string
18
+ */
19
+ protected $_fileTypeModel;
20
+
21
+ /**
22
+ *
23
+ * @var string
24
+ */
25
+ protected $_title;
26
+
27
+ /**
28
+ *
29
+ * @var string
30
+ */
31
+ protected $_fileUri;
32
+
33
+ /**
34
+ * Define attributes registry key prefix
35
+ *
36
+ * @var string
37
+ */
38
+ protected $_attributesRegistryPrefix = 'cms_block_columns_';
39
+
40
+ public function __construct() {
41
+ $this->_fileTypeModel = 'connector/types_general';
42
+ }
43
+
44
+ /**
45
+ * Creates xml content for translation
46
+ * Also defines filename uri for upload content to Smartling via API
47
+ * Defines content title for smartling translation table
48
+ *
49
+ * @param Mage_Cms_Model_Block|int $category $category
50
+ * @param int $project_id Profile ID
51
+ * @param int $sourceStoreId Source locale
52
+ * @return string
53
+ */
54
+ public function createTranslateContent($cmsBlock, $project_id, $sourceStoreId) {
55
+ if (is_numeric($cmsBlock)) {
56
+ $cmsBlock = $this->getContentTypeEntityModel()
57
+ ->setStoreId($sourceStoreId)
58
+ ->load((int)$cmsBlock);
59
+ }
60
+
61
+ if (!$cmsBlock->getId()){
62
+ Mage::getModel('adminhtml/session')->addError(
63
+ Mage::helper('connector')->__('Block does not exists')
64
+ );
65
+ return;
66
+ }
67
+
68
+ $content = Mage::getModel($this->_fileTypeModel);
69
+ $content->setContentGroupAttribute(array('block_id' => $cmsBlock->getId()));
70
+
71
+ //retrieve field from registry to translate
72
+ $flatColumnsCollection = Mage::registry($this->_attributesRegistryPrefix);
73
+
74
+ if(($flatColumnsCollection instanceof Smartling_Connector_Model_Resource_Translate_Fields_List_Block_Collection) == false ) {
75
+ //retrieve field to translate
76
+ $flatColumnsCollection = $this->getAttributes();
77
+
78
+ if (!$flatColumnsCollection->getSize()) {
79
+ $this->_getAdminSession()->addError(
80
+ Mage::helper('connector')->__("CMS Block columns weren't selected")
81
+ );
82
+
83
+ Mage::helper('connector')->log("CMS Block columns weren't selected", Zend_log::ERR);
84
+ return '-1';
85
+ } else {
86
+ Mage::register($this->_attributesRegistryPrefix, $flatColumnsCollection);
87
+ }
88
+ }
89
+
90
+ //create smartling type content
91
+ foreach ($flatColumnsCollection as $node_name => $row) {
92
+
93
+ $nodeOptions = array('attribute' => $node_name,
94
+ 'type' => 'textarea');
95
+
96
+ $content->setContent($cmsBlock->getData($node_name), $nodeOptions, 'htmlcontent');
97
+ }
98
+
99
+ //create full xml content for Api
100
+ $translateContent = $content->createContentFile();
101
+
102
+ $this->_fileUri = $this->formatFileUri('cms_block', $cmsBlock->getIdentifier(), $project_id);
103
+ $this->_title = $cmsBlock->getTitle();
104
+
105
+ return $translateContent;
106
+ }
107
+
108
+ /**
109
+ *
110
+ * @return \Smartling_Connector_Model_Resource_Translate_Fields_List_Block_Collection
111
+ */
112
+ public function getAttributes() {
113
+
114
+ $collection = Mage::getResourceModel('connector/translate_fields_list_block_collection');
115
+
116
+ // include items which attached to translate list
117
+ $collection->includeWithValue('is_attached', 1);
118
+
119
+ return $collection;
120
+ }
121
+
122
+ /**
123
+ *
124
+ * @return string
125
+ */
126
+ public function getFullFileUri() {
127
+ return Mage::getBaseDir('media') . DS . $this->getBaseFileDir()
128
+ . DS . $this->_fileUri;
129
+ }
130
+
131
+ /**
132
+ *
133
+ * @param array $translatedContent
134
+ * @param int $contentId
135
+ * @param array $storeId
136
+ * @param Smartling_Connector_Model_Content $contentModel
137
+ * @return bool
138
+ */
139
+ public function createContent($translatedContent, $contentId, $storeId){
140
+ /** @var Mage_Cms_Model_Block */
141
+ $block = Mage::getModel('cms/block')->load($contentId);
142
+ if (!$block->getId()){
143
+ return false;
144
+ }
145
+
146
+ $data = $block->getData();
147
+ unset($data['block_id']);
148
+ unset($data['creation_time']);
149
+ $blockData = array_merge($data, $translatedContent);
150
+
151
+ /** @var Mage_Cms_Model_Block */
152
+ $newBlock = Mage::getModel('cms/block');
153
+ $newBlock->setData($blockData);
154
+ $newBlock->setStores($storeId);
155
+
156
+ // Check if destination store grouped by content with other stores
157
+ if($this->countLinkedStores($block->getIdentifier(), $storeId)) {
158
+ $this->unlinkContentFromStore($contentId, $storeId);
159
+ }
160
+
161
+ if ($id = $this->checkIdentifier($block->getIdentifier(), $storeId)){
162
+ $newBlock->setId($id);
163
+ }
164
+
165
+ try{
166
+ $newBlock->save();
167
+ return $newBlock;
168
+ } catch (Exception $e) {
169
+
170
+ Mage::getSingleton('adminhtml/session')->addError(
171
+ Mage::helper('connector')->__($e->getMessage())
172
+ );
173
+
174
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
175
+
176
+ return false;
177
+ }
178
+ }
179
+
180
+ /**
181
+ *
182
+ * @return string
183
+ */
184
+ public function getContentTypeCode(){
185
+ return static::CONTENT_TYPE;
186
+ }
187
+
188
+ /**
189
+ *
190
+ * @return Mage_Catalog_Model_Category
191
+ */
192
+ public function getContentTypeEntityModel(){
193
+ return Mage::getModel('cms/block');
194
+ }
195
+
196
+ /**
197
+ *
198
+ * @param int $block_id
199
+ * @param int $store_id
200
+ */
201
+ protected function unlinkContentFromStore($block_id, $store_id) {
202
+ $resource = Mage::getSingleton('core/resource');
203
+ $connection = $resource->getConnection('write');
204
+
205
+ $tableName = Mage::getModel('cms/block')
206
+ ->getResource()
207
+ ->getTable('block_store');
208
+
209
+ $conditions = array();
210
+ $conditions[] = $connection->quoteInto('block_id=?', $block_id);
211
+ $conditions[] = $connection->quoteInto('store_id=?', $store_id);
212
+
213
+ $connection->delete($tableName, $conditions);
214
+ }
215
+
216
+ /**
217
+ * Count linked stores to specified content except destination store
218
+ *
219
+ * @param string $identifier
220
+ * @param string $store_id
221
+ * @return int
222
+ */
223
+ protected function countLinkedStores($identifier, $store_id) {
224
+ $table = $this->getContentTypeEntityModel()->getResource()
225
+ ->getMainTable();
226
+ $resource = Mage::getSingleton('core/resource');
227
+ $select = $resource->getConnection('read')->select()
228
+ ->from(array('cp' => $table))
229
+ ->joinInner(
230
+ array('cps' => $resource->getTableName('cms/block_store')),
231
+ 'cp.block_id = cps.block_id '
232
+ . ' and cp.identifier = "' . addslashes($identifier) . '" '
233
+ . ' and cps.store_id != ' . (int)$store_id,
234
+ array())
235
+ ->joinInner(
236
+ array('cps2' => $resource->getTableName('cms/block_store')),
237
+ 'cps.block_id = cps2.block_id and cps2.store_id = ' . (int)$store_id,
238
+ array());
239
+
240
+ $select->reset(Zend_Db_Select::COLUMNS)
241
+ ->columns('cp.block_id')
242
+ ->order('cps.store_id DESC');
243
+
244
+ return count($resource->getConnection('read')->fetchAll($select));
245
+ }
246
+
247
+ /**
248
+ *
249
+ * @param string $identifier
250
+ * @param string $store_id
251
+ * @return int
252
+ */
253
+ public function checkIdentifier($identifier, $store_id) {
254
+ $table = $this->getContentTypeEntityModel()->getResource()
255
+ ->getMainTable();
256
+ $resource = Mage::getSingleton('core/resource');
257
+ $select = $resource->getConnection('read')->select()
258
+ ->from(array('cp' => $table))
259
+ ->join(
260
+ array('cps' => $resource->getTableName('cms/block_store')),
261
+ 'cp.block_id = cps.block_id',
262
+ array())
263
+ ->where('cp.identifier = ?', $identifier)
264
+ ->where('cps.store_id = ?', $store_id);
265
+
266
+ $select->reset(Zend_Db_Select::COLUMNS)
267
+ ->columns('cp.block_id')
268
+ ->order('cps.store_id DESC')
269
+ ->limit(1);
270
+ return $resource->getConnection('read')->fetchOne($select);
271
+ }
272
+
273
+ /**
274
+ *
275
+ * @return boolean
276
+ */
277
+ public function saveNames() {
278
+ return parent::saveFlatNames('cms/block_store');
279
+ }
280
+ }
app/code/community/Smartling/Connector/Model/Content/CmsBlock/Observer.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_CmsBlock_Observer
9
+ {
10
+
11
+ /**
12
+ * upload content for translation if translation enabled
13
+ *
14
+ * @param Varien_Event_Observer $cmspage
15
+ */
16
+ public function sendBlockContentToTranslator(Varien_Event_Observer $object){
17
+ $modelObject = $object->getEvent()->getObject();
18
+ if ($modelObject instanceof Mage_Cms_Model_Block){
19
+ if ($modelObject->getLocales() && is_array($modelObject->getLocales())){
20
+ $locales = $modelObject->getData('locales');
21
+ /** @var $contentModel Smartling_Connector_Model_Content_CmsBlock */
22
+ $contentModel = Mage::getModel('connector/content_cmsBlock');
23
+ /** @var $translator Smartling_Connector_Model_Translator */
24
+ $translator = Mage::getModel('connector/translator');
25
+
26
+ /**
27
+ * create and save xml content for smartling translations
28
+ */
29
+ //$content = $contentModel->createTranslateContent($modelObject);
30
+ $type = Mage::helper('connector')
31
+ ->findTypeIdByTypeName(Smartling_Connector_Model_Content_CmsBlock::CONTENT_TYPE);
32
+ $processData = array(
33
+ 'type' => $type,
34
+ 'origin_content_id' => $modelObject->getId(),
35
+ 'content_title' => $modelObject->getTitle(),
36
+ );
37
+
38
+ // if ($content != ""){
39
+ // for ($i = 0; $i < sizeof ($locales); $i++) {
40
+ // $translator->uploadContent($contentModel, $locales[$i], $processData, $content);
41
+ // }
42
+ // } else {
43
+ // Mage::getSingleton('adminhtml/session')->addError(
44
+ // Mage::helper('connector')->__('Content does not exists')
45
+ // );
46
+ // }
47
+ for ($i = 0; $i < sizeof($locales); $i++) {
48
+ //$translator->uploadContent($contentModel, $locales[$i], $processData, $content);
49
+ $result = Mage::getResourceModel('connector/content')
50
+ ->addSingleItem($locales[$i], $processData);
51
+ if ($result && $result !== 0) {
52
+ $message = Mage::helper('connector')
53
+ ->__("New item added in translation queue for locale %s", $locales[$i]);
54
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
55
+ } elseif ($result == 0) {
56
+ $message = Mage::helper('connector')
57
+ ->__("Item already added in translation queue for locale %s", $locales[$i]);
58
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
59
+ } else {
60
+ $errors = "Unable to add Item to translation queue for locale {$locales[$i]}";
61
+ Mage::getSingleton('adminhtml/session')->addError($message);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
app/code/community/Smartling/Connector/Model/Content/CmsPage.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Cms
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_CmsPage
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface
11
+ {
12
+
13
+ /**
14
+ * define content type name
15
+ */
16
+ const CONTENT_TYPE = 'cmsPage';
17
+
18
+ /**
19
+ *
20
+ * @var string
21
+ */
22
+ protected $_fileTypeModel;
23
+
24
+ /**
25
+ *
26
+ * @var string
27
+ */
28
+ protected $_baseFileDir;
29
+
30
+ /**
31
+ *
32
+ * @var string
33
+ */
34
+ protected $_fileUri;
35
+
36
+ /**
37
+ * Define attributes registry key prefix
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_attributesRegistryPrefix = 'cms_page_columns_';
42
+
43
+ public function __construct() {
44
+ $this->_fileTypeModel = 'connector/types_general';
45
+ }
46
+
47
+ /**
48
+ * Creates xml content for translation
49
+ * Also defines filename uri for upload content to Smartling via API
50
+ * Defines content title for smartling translation table
51
+ *
52
+ * @param Mage_Cms_Model_Page|int $category $category
53
+ * @param int $project_id Profile ID
54
+ * @param int $sourceStoreId Source locale
55
+ * @return string
56
+ */
57
+ public function createTranslateContent($cmsPage, $project_id, $sourceStoreId) {
58
+
59
+ if (is_numeric($cmsPage)) {
60
+ $cmsPage = $this->getContentTypeEntityModel()
61
+ ->setStoreId($sourceStoreId)
62
+ ->load($cmsPage);
63
+ }
64
+
65
+ if (!$cmsPage->getId()){
66
+ Mage::getModel('adminhtml/session')->addError(
67
+ Mage::helper('connector')->__('Page does not exists')
68
+ );
69
+ return;
70
+ }
71
+
72
+ //retrieve field from registry to translate
73
+ $flatColumnsCollection = Mage::registry($this->_attributesRegistryPrefix);
74
+
75
+ if(($flatColumnsCollection instanceof Smartling_Connector_Model_Resource_Translate_Fields_List_Page_Collection) == false ) {
76
+ //retrieve field to translate
77
+ $flatColumnsCollection = $this->getAttributes();
78
+
79
+ if (!$flatColumnsCollection->getSize()) {
80
+ $this->_getAdminSession()->addError(
81
+ Mage::helper('connector')->__("CMS Page columns weren't selected")
82
+ );
83
+
84
+ Mage::helper('connector')->log("CMS Page columns weren't selected", Zend_log::ERR);
85
+ return '-1';
86
+ } else {
87
+ Mage::register($this->_attributesRegistryPrefix, $flatColumnsCollection);
88
+ }
89
+ }
90
+
91
+ $content = Mage::getModel($this->_fileTypeModel);
92
+ $content->setContentGroupAttribute(array('page_id' => $cmsPage->getId()));
93
+
94
+ //create smartling type content
95
+ foreach ($flatColumnsCollection as $node_name => $row) {
96
+
97
+ $nodeOptions = array('attribute' => $node_name,
98
+ 'type' => 'textarea');
99
+
100
+ $content->setContent($cmsPage->getData($node_name), $nodeOptions, 'htmlcontent');
101
+ }
102
+
103
+ // create full xml content for APi
104
+ $translateContent = $content->createContentFile();
105
+
106
+ $this->_fileUri = $this->formatFileUri('cms_page', $cmsPage->getIdentifier(), $project_id);
107
+ $this->_title = $cmsPage->getTitle();
108
+
109
+ return $translateContent;
110
+ }
111
+
112
+
113
+ /**
114
+ *
115
+ * @param array $translatedContent
116
+ * @param int $pageId
117
+ * @param int $storeId
118
+ * @param Smartling_Connector_Model_Content $contentModel
119
+ * @return bool
120
+ */
121
+ public function createContent($translatedContent, $pageId, $storeId){
122
+ /** @var $page Mage_Cms_Model_Page */
123
+ $page = Mage::getModel('cms/page')->load($pageId);
124
+
125
+ if (!$page->getId()){
126
+ return false;
127
+ }
128
+
129
+ $data = $page->getData();
130
+ unset($data['page_id']);
131
+ unset($data['creation_time']);
132
+ $pageData = array_merge($data, $translatedContent);
133
+ /** @var $newPage Mage_Cms_Model_Page */
134
+ $newPage = Mage::getModel('cms/page');
135
+ $newPage->setData($pageData);
136
+ $newPage->setStores($storeId);
137
+
138
+ // Check if destination store grouped by content with other stores
139
+ if($this->countLinkedStores($page->getIdentifier(), $storeId)) {
140
+ $this->unlinkContentFromStore($pageId, $storeId);
141
+ }
142
+
143
+ if ($id = $this->checkIdentifier($page->getIdentifier(), $storeId)) {
144
+ $newPage->setId($id);
145
+ }
146
+
147
+ try {
148
+ $newPage->save();
149
+ return $newPage;
150
+ } catch (Exception $e) {
151
+
152
+ Mage::getSingleton('adminhtml/session')->addError(
153
+ Mage::helper('connector')->__($e->getMessage()));
154
+
155
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
156
+
157
+ return false;
158
+ }
159
+ }
160
+
161
+ /**
162
+ *
163
+ * @param int $page_id
164
+ * @param int $store_id
165
+ */
166
+ protected function unlinkContentFromStore($page_id, $store_id) {
167
+ $resource = Mage::getSingleton('core/resource');
168
+ $connection = $resource->getConnection('write');
169
+
170
+ $tableName = Mage::getModel('cms/page')
171
+ ->getResource()
172
+ ->getTable('page_store');
173
+
174
+ $conditions = array();
175
+ $conditions[] = $connection->quoteInto('page_id=?', $page_id);
176
+ $conditions[] = $connection->quoteInto('store_id=?', $store_id);
177
+
178
+ $connection->delete($tableName, $conditions);
179
+ }
180
+
181
+ /**
182
+ * Count linked stores to specified content except destination store
183
+ *
184
+ * @param string $identifier
185
+ * @param string $store_id
186
+ * @return int
187
+ */
188
+ protected function countLinkedStores($identifier, $store_id) {
189
+ $table = $this->getContentTypeEntityModel()->getResource()
190
+ ->getMainTable();
191
+ $resource = Mage::getSingleton('core/resource');
192
+ $select = $resource->getConnection('read')->select()
193
+ ->from(array('cp' => $table))
194
+ ->joinInner(
195
+ array('cps' => $resource->getTableName('cms/page_store')),
196
+ 'cp.page_id = cps.page_id '
197
+ . ' and cp.identifier = "' . addslashes($identifier) . '" '
198
+ . ' and cps.store_id != ' . (int)$store_id,
199
+ array())
200
+ ->joinInner(
201
+ array('cps2' => $resource->getTableName('cms/page_store')),
202
+ 'cps.page_id = cps2.page_id and cps2.store_id = ' . (int)$store_id,
203
+ array());
204
+
205
+ $select->reset(Zend_Db_Select::COLUMNS)
206
+ ->columns('cp.page_id')
207
+ ->order('cps.store_id DESC');
208
+
209
+ return count($resource->getConnection('read')->fetchAll($select));
210
+ }
211
+
212
+ /**
213
+ *
214
+ * @return \Smartling_Connector_Model_Resource_Translate_Fields_List_Page_Collection
215
+ */
216
+ public function getAttributes() {
217
+
218
+ $collection = Mage::getResourceModel('connector/translate_fields_list_page_collection');
219
+
220
+ // include items which attached to translate list
221
+ $collection->includeWithValue('is_attached', 1);
222
+
223
+ return $collection;
224
+ }
225
+
226
+ /**
227
+ *
228
+ * @return string
229
+ */
230
+ public function getContentTypeCode(){
231
+ return static::CONTENT_TYPE;
232
+ }
233
+
234
+ /**
235
+ *
236
+ * @return Mage_Catalog_Model_Category
237
+ */
238
+ public function getContentTypeEntityModel(){
239
+ return Mage::getModel('cms/page');
240
+ }
241
+
242
+ /**
243
+ *
244
+ * @param string $identifier
245
+ * @param string $store
246
+ * @return int
247
+ */
248
+ public function checkIdentifier($identifier, $store) {
249
+ $table = $this->getContentTypeEntityModel()->getResource()
250
+ ->getMainTable();
251
+ $resource = Mage::getSingleton('core/resource');
252
+ $select = $resource->getConnection('read')->select()
253
+ ->from(array('cp' => $table))
254
+ ->join(
255
+ array('cps' => $resource->getTableName('cms/page_store')),
256
+ 'cp.page_id = cps.page_id',
257
+ array())
258
+ ->where('cp.identifier = ?', $identifier)
259
+ ->where('cps.store_id IN (?)', $store);
260
+
261
+ $select->reset(Zend_Db_Select::COLUMNS)
262
+ ->columns('cp.page_id')
263
+ ->order('cps.store_id DESC')
264
+ ->limit(1);
265
+ return $resource->getConnection('read')->fetchOne($select);
266
+ }
267
+
268
+ /**
269
+ *
270
+ * @return boolean
271
+ */
272
+ public function saveNames() {
273
+ return parent::saveFlatNames('cms/page_store');
274
+ }
275
+ }
app/code/community/Smartling/Connector/Model/Content/CmsPage/Observer.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_CmsPage_Observer
9
+ {
10
+
11
+ /**
12
+ * upload content for translation if translation enabled
13
+ *
14
+ * @param Varien_Event_Observer $cmspage
15
+ */
16
+ public function getPageInfo(Varien_Event_Observer $cmspage){
17
+ $page = $cmspage->getEvent()->getDataObject();
18
+ if (is_array($page->getData('locales'))) {
19
+ $locales = $page->getData('locales');
20
+ /** @var $contentModel Smartling_Connector_Model_Content_CmsPage */
21
+ $contentModel = Mage::getModel('connector/content_cmsPage');
22
+ /** @var $translator Smartling_Connector_Model_Translator */
23
+ $translator = Mage::getModel('connector/translator');
24
+ /**
25
+ * create and save xml content for smartling translations
26
+ */
27
+ //$content = $contentModel->createTranslateContent($page);
28
+ $type = Mage::helper('connector')
29
+ ->findTypeIdByTypeName(Smartling_Connector_Model_Content_CmsPage::CONTENT_TYPE);
30
+ $processData = array(
31
+ 'type' => $type,
32
+ 'origin_content_id' => $page->getId(),
33
+ 'content_title' => $page->getTitle(),
34
+ );
35
+ /**
36
+ * upload translations content
37
+ */
38
+ // if ($content != ""){
39
+ // for ($i = 0; $i < sizeof ($locales); $i++) {
40
+ // $translator->uploadContent($contentModel, $locales[$i], $processData, $content);
41
+ // }
42
+ // } else {
43
+ // Mage::getSingleton('adminhtml/session')->addError(
44
+ // Mage::helper('connector')->__('File does not exists'));
45
+ // }
46
+ for ($i = 0; $i < sizeof($locales); $i++) {
47
+ //$translator->uploadContent($contentModel, $locales[$i], $processData, $content);
48
+ $result = Mage::getResourceModel('connector/content')
49
+ ->addSingleItem($locales[$i], $processData);
50
+ if ($result && $result !== 0) {
51
+ $message = Mage::helper('connector')
52
+ ->__("New item added in translation queue for locale %s", $locales[$i]);
53
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
54
+ } elseif ($result == 0) {
55
+ $message = Mage::helper('connector')
56
+ ->__("Item already added in translation queue for locale %s", $locales[$i]);
57
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
58
+ } else {
59
+ $errors = "Unable to add Item to translation queue for locale {$locales[$i]}";
60
+ Mage::getSingleton('adminhtml/session')->addError($message);
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ }
app/code/community/Smartling/Connector/Model/Content/EavEntityInterface.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Workflow for atributes with options and any system entities relation to EAV models
5
+ *
6
+ */
7
+ interface Smartling_Connector_Model_Content_EavEntityInterface {
8
+ public function getTranslatedAttributesOptions($content);
9
+ }
app/code/community/Smartling/Connector/Model/Content/Interface.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Description of Interface
6
+ *
7
+ * @author Smartling
8
+ */
9
+ interface Smartling_Connector_Model_Content_Interface
10
+ {
11
+
12
+ /**
13
+ * Creates the same content for other locales
14
+ *
15
+ * @param array $translatedContent
16
+ * @param int $originContentId
17
+ * @param array $storeId
18
+ * @param Smartling_Connector_Model_Content $contentModel
19
+ */
20
+ public function createContent($translatedContent, $originContentId, $storeId);
21
+
22
+ /**
23
+ * Creates content data for smartling translation
24
+ *
25
+ * @param mixed $contentId
26
+ * @param int $project_id Profile ID
27
+ * @param int $sourceStoreId Source locale
28
+ * @return string
29
+ */
30
+ public function createTranslateContent($contentId, $project_id, $sourceStoreId);
31
+
32
+ /**
33
+ * Return parsed response
34
+ *
35
+ * @param string $translatedContent
36
+ */
37
+ public function getTranslatedContent($translatedContent);
38
+
39
+ /**
40
+ * Return original content model
41
+ */
42
+ public function getContentTypeEntityModel();
43
+
44
+ /**
45
+ *
46
+ * @param string $content
47
+ * @param string $fileUri
48
+ * @param array $item
49
+ */
50
+ public function uploadContent($content, $fileUri, $item);
51
+
52
+ }
app/code/community/Smartling/Connector/Model/Content/Localization.php ADDED
@@ -0,0 +1,336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Attibute
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Localization
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface
11
+ {
12
+
13
+ const CONTENT_TYPE = 'localization';
14
+
15
+ /**
16
+ * define entity type
17
+ *
18
+ * @var string
19
+ */
20
+ protected $_entityType = 'translate';
21
+
22
+ /**
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_fileTypeModel;
27
+
28
+ /**
29
+ *
30
+ * @var string
31
+ */
32
+ protected $_fileUri;
33
+
34
+ /**
35
+ *
36
+ * @var string
37
+ */
38
+ protected $_uploadFilePath;
39
+
40
+
41
+ protected $_comments = array(
42
+ 'smartling.field_separator'=> ',',
43
+ 'smartling.string_encloser' => '"',
44
+ 'smartling.string_format_paths' => 'html : 2',
45
+ 'smartling.paths' => '2',
46
+ 'smartling.source_key_paths' => '1',
47
+ 'smartling.placeholder_format_custom' => '(%\w{1})|(\{\{.+\}\})'
48
+ );
49
+
50
+ public function __construct() {
51
+ parent::__construct();
52
+ $this->_fileTypeModel = 'connector/types_general';
53
+ }
54
+
55
+
56
+ /**
57
+ * Creates xml content for translation
58
+ * Also defines filename uri for upload content to Smartling via API
59
+ * Defines content title for smartling translation table
60
+ *
61
+ * @param Smartling_Connector_Model_Content_Localization|int $localization
62
+ * @param int $project_id Profile ID
63
+ * @param int $sourceStoreId Source locale
64
+ * @return string
65
+ */
66
+ public function createTranslateContent($localization, $project_id, $sourceStoreId) {
67
+
68
+ if (is_numeric($localization)) {
69
+ $localization = $this->getContentTypeEntityModel()
70
+ ->setStoreId($sourceStoreId)
71
+ ->load($localization);
72
+ }
73
+
74
+ if (!$localization->getId()){
75
+ Mage::getModel('adminhtml/session')->addError(
76
+ Mage::helper('connector')->__('File does not exists')
77
+ );
78
+ return false;
79
+ }
80
+
81
+ $this->setUploadFilePath($localization->getFilePath());
82
+
83
+ $this->_fileUri = $this->formatFileUri('localization_file', $localization->getId(), $project_id);
84
+ $this->_title = $localization->getTitle();
85
+
86
+ return $localization->getFilePath();
87
+ }
88
+
89
+
90
+ /**
91
+ *
92
+ * @param array $translatedContent
93
+ * @param int $fileId
94
+ * @param int $storeId
95
+ * @param Smartling_Connector_Model_Content $contentModel
96
+ * @return bool
97
+ */
98
+ public function createContent($translatedContent, $fileId, $storeId){
99
+
100
+ $translatedContentData = Mage::registry('content_translate_row_data');
101
+
102
+ $destinationLocation =
103
+ $this->getDestinationLocation($translatedContentData['store_id'],
104
+ $translatedContentData['source_store_id'],
105
+ $translatedContentData['file_path']);
106
+
107
+ if(!$destinationLocation) {
108
+ Mage::helper('connector')->log("Destination directory has not specified", Zend_log::ERR);
109
+ return false;
110
+ }
111
+
112
+ if($this->filePutContent($destinationLocation, $translatedContent) === false) {
113
+ Mage::helper('connector')->log("Can not create {$destinationLocation} file", Zend_log::ERR);
114
+ return false;
115
+ }
116
+
117
+ return true;
118
+ }
119
+
120
+ /**
121
+ *
122
+ * @param string $filePath
123
+ * @param string $content
124
+ * @return boolean
125
+ */
126
+ public function filePutContent($filePath, $content) {
127
+
128
+ try {
129
+ if(!is_dir(dirname($filePath))) {
130
+ $this->createDirRecursive(dirname($filePath));
131
+ }
132
+
133
+ $handle = fopen($filePath, 'w');
134
+
135
+ if ($handle === false) {
136
+ Mage::throwException("Cannot open file ($filePath)");
137
+ }
138
+
139
+ if (fwrite($handle, $content) === false) {
140
+ Mage::throwException("Cannot write to file ($filePath)");
141
+ }
142
+
143
+ fclose($handle);
144
+
145
+ } catch (Mage_Core_Exception $e) {
146
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
147
+ return false;
148
+ }
149
+
150
+ return true;
151
+ }
152
+
153
+ private function createDirRecursive($path, $permissions = 0777) {
154
+ if (is_dir($path)) return true;
155
+ $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
156
+ $return = $this->createDirRecursive($prev_path, $permissions);
157
+ return ($return && is_writable($prev_path)) ? mkdir($path) : false;
158
+ }
159
+
160
+ /**
161
+ *
162
+ * @return string
163
+ */
164
+ public function getContentTypeCode(){
165
+ return static::CONTENT_TYPE;
166
+ }
167
+
168
+ /**
169
+ *
170
+ * @return Mage_Catalog_Model_Category
171
+ */
172
+ public function getContentTypeEntityModel(){
173
+ return Mage::getModel('connector/localization_files_index');
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @return boolean
179
+ */
180
+ public function saveNames() {
181
+
182
+ try {
183
+
184
+ $resource = Mage::getSingleton('core/resource');
185
+ $_adapter = $resource->getConnection('core_write');
186
+
187
+ $model = $this->getContentTypeEntityModel();
188
+
189
+ $entityTableName = $resource->getTableName($model->getResourceName());
190
+ $contentTableName = $resource->getTableName('connector/translate_content');
191
+
192
+ $updateNamesQuery = "UPDATE {$contentTableName} c "
193
+ . " JOIN {$entityTableName} AS `e` ON c.content_title = '' "
194
+ . " AND c.origin_content_id = e.id "
195
+ . " SET c.content_title = substring_index(e.file_path, '/', -1)";
196
+
197
+ $_adapter->query($updateNamesQuery);
198
+
199
+ } catch (Exception $ex) {
200
+ Mage::helper('connector')->log("Current entity names (Flat Model) weren't updated: " . $ex->getMessage(), Zend_log::ERR);
201
+ return false;
202
+ }
203
+
204
+ return true;
205
+
206
+ }
207
+
208
+ /**
209
+ *
210
+ * @param string $path
211
+ * @param string $fileUri
212
+ * @param array $item
213
+ * @return bool
214
+ */
215
+ public function uploadContent($path, $fileUri, $item) {
216
+
217
+ /** @var $translator Smartling_Connector_Model_Translator */
218
+ $translator = Mage::getModel('connector/translator',
219
+ array('apiKey' => $item['api_key'],
220
+ 'projectId' => $item['project_code'],
221
+ 'project_id' => $item['project_id'],
222
+ 'locales' => $item['locales']
223
+ )
224
+ );
225
+ $translator->setFileType(Smartling_Connector_Model_Translator::FILE_TYPE_CSV);
226
+
227
+ $response = $translator->uploadTranslateData($path, $fileUri, $this->_comments);
228
+
229
+ Mage::helper('connector')->log($response, Zend_log::INFO);
230
+
231
+ return $translator->isSuccessResponse($response);
232
+ }
233
+
234
+ /**
235
+ *
236
+ * @return string|bool
237
+ */
238
+ public function getFileUri() {
239
+ if(strlen($this->_fileUri)) {
240
+ return $this->_fileUri . '.csv';
241
+ } else {
242
+ return false;
243
+ }
244
+ }
245
+
246
+ public function getComments() {
247
+ return implode("\n", $this->_comments) . "\n";
248
+ }
249
+
250
+ public function setUploadFilePath($path) {
251
+ $this->_uploadFilePath = $path;
252
+ }
253
+
254
+ /**
255
+ *
256
+ * @return string
257
+ */
258
+ public function getUploadFilePath() {
259
+ return $this->_uploadFilePath;
260
+ }
261
+
262
+ /**
263
+ * Return parsed response
264
+ *
265
+ * @param string $translatedContent
266
+ * @return string
267
+ */
268
+ public function getTranslatedContent($translatedContent) {
269
+ return $translatedContent; // return itself as CSV file dont' need modifications
270
+ }
271
+
272
+ /**
273
+ *
274
+ * @param int $destination_store_id
275
+ * @param int $source_store_id
276
+ * @param string $file_source_path
277
+ * @return boolean
278
+ */
279
+ protected function getDestinationLocation($destination_store_id, $source_store_id, $file_source_path) {
280
+
281
+ $locales = $this->gelLocalizationDirectories($destination_store_id, $source_store_id);
282
+
283
+ if(sizeof($locales) != 2) {
284
+ Mage::helper('connector')->log('Source and destination locales has not detected', Zend_log::ERR);
285
+ return false;
286
+ }
287
+
288
+ $destinationFile = str_replace($locales[$source_store_id],
289
+ $locales[$destination_store_id],
290
+ $file_source_path);
291
+
292
+ return $destinationFile;
293
+ }
294
+
295
+ /**
296
+ *
297
+ * @param int $destination_store_id
298
+ * @param int $source_store_id
299
+ * @return boolean|array
300
+ */
301
+ public function gelLocalizationDirectories($destination_store_id, $source_store_id) {
302
+
303
+ $locales = array();
304
+ $storesCollection = Mage::getModel('core/store')->getCollection();
305
+ $storesCollection->addFieldToFilter('store_id',
306
+ array('in' =>
307
+ array(
308
+ $destination_store_id,
309
+ $source_store_id
310
+ )
311
+ ));
312
+
313
+ try {
314
+
315
+ if($storesCollection->getSize() < 2) {
316
+ Mage::throwException("Store localization directory hasn't specified");
317
+ }
318
+
319
+ foreach ($storesCollection as $storeParams) {
320
+ $storeLocalizationDir = $storeParams->getStoreLocalizationDir();
321
+
322
+ if(is_null($storeLocalizationDir)) {
323
+ Mage::throwException("Store localization directory hasn't specified. Store name: {$storeParams->getName()}");
324
+ }
325
+ $locales[$storeParams->getId()] = $storeParams->getStoreLocalizationDir();
326
+ }
327
+
328
+ } catch (Mage_Core_Exception $e) {
329
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
330
+ return false;
331
+ }
332
+
333
+ return $locales;
334
+
335
+ }
336
+ }
app/code/community/Smartling/Connector/Model/Content/Product.php ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Product
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Product
9
+ extends Smartling_Connector_Model_Content_Abstract
10
+ implements Smartling_Connector_Model_Content_Interface,
11
+ Smartling_Connector_Model_Content_EavEntityInterface
12
+ {
13
+
14
+ const CONTENT_TYPE = 'product';
15
+
16
+ /**
17
+ * define entity type
18
+ *
19
+ * @var string
20
+ */
21
+ protected $_entityType = 'catalog_product';
22
+
23
+ /**
24
+ * Define attributes registry key prefix
25
+ *
26
+ * @var string
27
+ */
28
+ protected $_attributesRegistryPrefix = 'products_attributes_';
29
+
30
+ /**
31
+ * Smartling content types
32
+ *
33
+ * @var array
34
+ */
35
+ protected $_smartlingContentTypes = array('content', 'htmlcontent');
36
+
37
+ /**
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_fileTypeModel;
42
+
43
+ public function __construct() {
44
+ parent::__construct();
45
+ $this->_fileTypeModel = 'connector/types_general';
46
+ }
47
+
48
+ /**
49
+ * Creates the same content for other locales
50
+ *
51
+ * @param array $translatedContent
52
+ * @param int $originContentId
53
+ * @param int $storeId
54
+ * @param Smartling_Connector_Model_Content $contentModel
55
+ */
56
+ public function createContent($translatedContent, $originContentId, $storeId) {
57
+
58
+ if(!is_array($translatedContent)) {
59
+ return false;
60
+ }
61
+
62
+ foreach ($translatedContent as $key => $value) {
63
+ if(is_array($value)) {
64
+ $translatedContent[$key] = implode(',', $value);
65
+ }
66
+ }
67
+
68
+ $action = Mage::getModel('catalog/resource_product_action');
69
+ $action->updateAttributes(array($originContentId), $translatedContent, $storeId);
70
+ }
71
+
72
+ /**
73
+ * Creates xml content for translation
74
+ * Also defines filename uri for upload content to Smartling via API
75
+ * Defines content title for smartling translation table
76
+ *
77
+ * @param Mage_Catalog_Model_Product|int $category $category
78
+ * @param int $project_id Profile ID
79
+ * @param int $sourceStoreId Source locale
80
+ * @return string
81
+ */
82
+ public function createTranslateContent($product, $project_id, $sourceStoreId) {
83
+
84
+ if (is_numeric($product)) {
85
+ $product = $this->getContentTypeEntityModel()
86
+ ->setStoreId($sourceStoreId)
87
+ ->load($product);
88
+ }
89
+
90
+ $attributesKeyObject = $this->_attributesRegistryPrefix . $product->getAttributeSetId();
91
+
92
+ $attributes = Mage::registry($attributesKeyObject);
93
+
94
+ if(!is_array($attributes)) {
95
+
96
+ $attributesCollection = $this->getAttributes($product->getAttributeSetId());
97
+
98
+ if (!$attributesCollection->getSize()) {
99
+ $this->_getAdminSession()->addError(
100
+ Mage::helper('connector')->__("product attributes weren't selected")
101
+ );
102
+
103
+ Mage::helper('connector')->log("Attributes weren't selected", Zend_log::ERR);
104
+
105
+ return '-1';
106
+ } else {
107
+ $attributes = $this->formatAttributes($attributesCollection);
108
+ Mage::register($attributesKeyObject, $attributes);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * @TODO group entities at Smartling_Connector_ServiceController by entity type
114
+ * and load collection. createTranslateContent method should use collection item.
115
+ */
116
+
117
+ $productsCollection = Mage::getModel('catalog/product')->getCollection()
118
+ ->addAttributeToSelect('*')
119
+ ->addIdFilter($product->getId());
120
+
121
+ $product = $productsCollection->getFirstItem();
122
+
123
+ $content = Mage::getModel($this->_fileTypeModel);
124
+ $content->setContentGroupAttribute(array('product_id' => $product->getId()));
125
+
126
+ //create smartling type content
127
+ foreach ($this->_smartlingContentTypes as $type) {
128
+
129
+ if (!empty($attributes[$type])) {
130
+
131
+ $count = sizeof($attributes[$type]);
132
+ for ($i = 0; $i < $count; $i++) {
133
+ $decoratorType = $type;
134
+
135
+ $contentValue = $product->getData($attributes[$type][$i]['attribute']);
136
+ if ($contentValue){
137
+
138
+ switch ($attributes[$type][$i]['type']) {
139
+ case 'select':
140
+ case 'multiselect':
141
+
142
+ $contentValueAttributes = $product->getAttributeText($attributes[$type][$i]['attribute']);
143
+
144
+ // combine options ids with values
145
+ if(is_array($contentValueAttributes)) { // multiselect
146
+ $attributeIds = explode(',',$contentValue);
147
+
148
+ if(sizeof($attributeIds) == sizeof($contentValueAttributes)) {
149
+ $contentValue = array_combine($attributeIds, $contentValueAttributes);
150
+ } else {
151
+ continue;
152
+ }
153
+ } else { // simple select
154
+ $contentValue = array($contentValue => $contentValueAttributes);
155
+ }
156
+
157
+ break;
158
+ default:
159
+ if($type != 'htmlcontent' && strlen($contentValue) != strlen(strip_tags($contentValue))) {
160
+ $decoratorType = 'htmlcontent';
161
+ }
162
+ break;
163
+ }
164
+
165
+ if(is_array($contentValue)) {
166
+ $decoratorType = 'list';
167
+ }
168
+
169
+ $content->setContent($contentValue, $attributes[$type][$i], $decoratorType);
170
+
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ //create full xml content for Api
177
+ $translateContent = $content->createContentFile();
178
+
179
+ $filename = ($product->getUrlKey()) ? $product->getUrlKey() . '_prod_id' : 'product';
180
+ $this->_fileUri = $this->formatFileUri($filename, $product->getId(), $project_id);
181
+ $this->_title = $product->getName();
182
+
183
+ return $translateContent;
184
+ }
185
+
186
+ /**
187
+ *
188
+ * @return type
189
+ */
190
+ public function getAttributes($attribute_set_id = 0) {
191
+
192
+ $resource = Mage::getModel('core/resource');
193
+ $systemAttributes = array_keys(Mage::getStoreConfig('connector/translate_attributes/catalog_product'));
194
+
195
+ $collection = Mage::getResourceModel('catalog/product_attribute_collection')
196
+ ->addVisibleFilter()
197
+ ->addFieldToFilter('is_global', Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE)
198
+ ->addFieldToFilter('attribute_code', array('nin' => $systemAttributes));
199
+
200
+ if($attribute_set_id) {
201
+ $collection->setAttributeSetFilter($attribute_set_id);
202
+ }
203
+
204
+ $collection->getSelect()
205
+ ->joinInner(
206
+ array('ia' => $resource->getTableName('connector/translate_attributes')),
207
+ 'ia.attribute_id = main_table.attribute_id', array()
208
+ );
209
+
210
+ return $collection;
211
+ }
212
+
213
+ /**
214
+ * Return parsed response
215
+ *
216
+ * @param string $translatedContent
217
+ */
218
+ public function getTranslatedAttributesOptions($content) {
219
+ return parent::getTranslatedAttributesOptions($content);
220
+ }
221
+
222
+ /**
223
+ *
224
+ * @return Mage_Catalog_Model_Product
225
+ */
226
+ public function getContentTypeEntityModel() {
227
+ return Mage::getModel('catalog/product');
228
+ }
229
+
230
+ /**
231
+ *
232
+ * @return string
233
+ */
234
+ public function getContentTypeCode(){
235
+ return static::CONTENT_TYPE;
236
+ }
237
+
238
+ /**
239
+ * @deprecated since version 0.2.2
240
+ * @param int $content_id
241
+ * @return string
242
+ */
243
+ public function setContentTitle($content_id) {
244
+ $productModel = Mage::getModel('catalog/product')->load($content_id);
245
+ $this->_title = $productModel->getName();
246
+ }
247
+
248
+ /**
249
+ *
250
+ * @return boolean
251
+ */
252
+ public function saveNames() {
253
+ return parent::saveEavNames();
254
+ }
255
+ }
app/code/community/Smartling/Connector/Model/Content/Product/Observer.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Product_Observer
9
+ {
10
+
11
+ /**
12
+ * upload content for translation if translation enabled
13
+ *
14
+ * @param Varien_Event_Observer $object
15
+ */
16
+ public function sendProductContentToTranslator(Varien_Event_Observer $object){
17
+ $product = $object->getEvent()->getProduct();
18
+ if (is_array($product->getData('locales'))) {
19
+ $locales = $product->getData('locales');
20
+ //if ($product->getId() && $product->getTranslationIsActive()){
21
+ $contentModel = Mage::getModel('connector/content_product');
22
+ $translator = Mage::getModel('connector/translator');
23
+
24
+ //create and save xml content for smartling translations
25
+ //$content = $contentModel->createTranslateContent($product);
26
+
27
+ $processData = array(
28
+ 'type' => Mage::helper('connector')
29
+ ->findTypeIdByTypeName(Smartling_Connector_Model_Content_Product::CONTENT_TYPE),
30
+ 'origin_content_id' => $product->getId(),
31
+ 'content_title' => $product->getName(),
32
+ );
33
+
34
+ // if ($content != ""){
35
+ // for ($i = 0; $i < sizeof ($locales); $i++) {
36
+ // $translator->uploadContent($contentModel, $locales[$i], $processData, $content);
37
+ // }
38
+ // }
39
+ for ($i = 0; $i < sizeof($locales); $i++) {
40
+ //$translator->uploadContent($contentModel, $locales[$i], $processData, $content);
41
+ $result = Mage::getResourceModel('connector/content')
42
+ ->addSingleItem($locales[$i], $processData);
43
+ if ($result && $result !== 0) {
44
+ $message = Mage::helper('connector')
45
+ ->__("New item added in translation queue for locale %s", $locales[$i]);
46
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
47
+ } elseif ($result == 0) {
48
+ $message = Mage::helper('connector')
49
+ ->__("Item already added in translation queue for locale %s", $locales[$i]);
50
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
51
+ } else {
52
+ $errors = "Unable to add Item to translation queue for locale {$locales[$i]}";
53
+ Mage::getSingleton('adminhtml/session')->addError($message);
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Add locales params to product for sending product content to Smartling
61
+ *
62
+ *
63
+ * @param Varien_Event_Observer $object
64
+ */
65
+ public function addTranslationOptions (Varien_Event_Observer $object) {
66
+ $request = $object->getEvent()->getRequest();
67
+ if ($locales = $request->getParam('locales')) {
68
+ $product = $object->getEvent()->getProduct();
69
+ $product->setData('locales', $locales);
70
+ }
71
+ }
72
+ }
app/code/community/Smartling/Connector/Model/Content/Types.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Content_Types
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ protected function _construct() {
13
+ $this->_init('connector/content_types');
14
+ }
15
+
16
+ /**
17
+ *
18
+ * @param string $type
19
+ * @return Mage_Core_Model_Resource_Db_Collection
20
+ */
21
+ public function getTypeDetails($type) {
22
+ $contentType = Mage::getModel('connector/content_types')->getCollection()
23
+ ->addFieldToFilter('type_name', array('eq' => $type));
24
+ if ($contentType->getSize() == 0){
25
+ Mage::getSingleton('admin/session')->addError(
26
+ 'Content type does not exists'
27
+ );
28
+ }
29
+
30
+ $type = $contentType->getFirstItem();
31
+ return $type;
32
+ }
33
+ }
app/code/community/Smartling/Connector/Model/Localization/Files.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Model_Localization_Files
8
+ {
9
+
10
+ /**
11
+ * List of scanned files
12
+ * @var array
13
+ */
14
+ protected $_fileList = array();
15
+
16
+ /**
17
+ * List of indexed files in storage
18
+ * @var array
19
+ */
20
+ protected $_indexedFiles = array();
21
+
22
+ protected $_resource;
23
+ protected $_adapter;
24
+
25
+ public function __construct() {
26
+ $this->_resource = Mage::getSingleton('core/resource');
27
+ $this->_adapter = $this->_resource->getConnection('write');
28
+ $this->_fileList = array();
29
+ }
30
+
31
+ /**
32
+ * Join list of files to $_fileList
33
+ * @param string $path
34
+ */
35
+ public function joinFiles() {
36
+
37
+ $params = func_get_args();
38
+
39
+ if(!sizeof($params)) return false;
40
+
41
+ foreach ($params as $path) {
42
+
43
+ if(strpos($path, 'app/design/frontend/base') !== false) {
44
+ continue;
45
+ }
46
+
47
+ $fileList = glob($path);
48
+ if($fileList) {
49
+ $this->_fileList = array_merge($this->_fileList, $fileList);
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @return array
57
+ */
58
+ public function getFileList() {
59
+ return $this->_fileList;
60
+ }
61
+
62
+ /**
63
+ * Get files list with actual files modification time
64
+ * @return array
65
+ */
66
+ public function getFileListFormated() {
67
+
68
+ $fileList = array();
69
+ if(sizeof($this->_fileList)) {
70
+ foreach ($this->_fileList as $key => $file_path) {
71
+ $updated_at = date('Y-m-d H:i:s', filemtime($file_path));
72
+ $fileList[$key] = array('file_path' => $file_path,
73
+ 'updated_at' => $updated_at);
74
+ }
75
+ }
76
+
77
+ return $fileList;
78
+ }
79
+
80
+ /**
81
+ * Return cross data collection of exist locales
82
+ * in store view and smarling profiles.
83
+ *
84
+ * @return \Smartling_Connector_Model_Resource_Projects_Locales_Collection
85
+ */
86
+ public function getAvailableLocales() {
87
+ $resource = Mage::getSingleton('core/resource');
88
+
89
+ $collection = Mage::getModel('connector/projects_locales')->getCollection();
90
+
91
+ $storeViewTableName = $resource->getTableName('core_store');
92
+ $storeGroupTableName = $resource->getTableName('core_store_group');
93
+
94
+ $collection->getSelect()
95
+ ->reset(Zend_Db_Select::COLUMNS)
96
+ ->joinInner(array('cs' => $storeViewTableName),
97
+ 'main_table.store_id = cs.store_id',
98
+ array())
99
+ ->joinInner(array('csg' => $storeGroupTableName),
100
+ 'cs.group_id = csg.default_store_id',
101
+ array())
102
+ ->joinInner(array('cs2' => $storeViewTableName),
103
+ 'csg.default_store_id = cs2.store_id',
104
+ array('store_localization_dir'))
105
+ ->group('cs2.store_id');
106
+
107
+ return $collection;
108
+ }
109
+
110
+
111
+ /**
112
+ *
113
+ * @param string $dir_name
114
+ * @param string $file_path
115
+ * @return bool
116
+ */
117
+ public function isFileInIndex($dir_name, $file_path) {
118
+
119
+ $collection = Mage::getModel('connector/localization_files_index')
120
+ ->getCollection()
121
+ ->addFieldToFilter('dir_name', array('like' => $dir_name))
122
+ ->addFieldToFilter('file_path', array('like' => $file_path));
123
+
124
+ return ($collection->getSize() > 0);
125
+ }
126
+
127
+ public function initIndexedFileList() {
128
+ $collection = Mage::getModel('connector/localization_files_index')
129
+ ->getCollection();
130
+
131
+ foreach ($collection as $fileInfo) {
132
+ $this->_indexedFiles[$fileInfo['file_path']] = $fileInfo;
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Return info of indexed file from storage
138
+ * @param string $path
139
+ * @return array
140
+ */
141
+ public function getFileInfo($path) {
142
+ if(array_key_exists($path, $this->_indexedFiles)) {
143
+ return $this->_indexedFiles[$path];
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Save scanned file list to storage
149
+ * @param string $localeCode
150
+ * @param array $fileList
151
+ * @return boolean
152
+ */
153
+ public function saveFiles($localeCode, $fileList = array()) {
154
+
155
+ if(!sizeof($fileList)) {
156
+ $fileList = $this->getFileListFormated();
157
+ }
158
+
159
+ if(!sizeof($fileList)) {
160
+ return false;
161
+ }
162
+
163
+ foreach ($fileList as $file) {
164
+
165
+ $storagedFileInfo = $this->getFileInfo($file['file_path']);
166
+
167
+ if(!array_key_exists('updated_at', $storagedFileInfo)
168
+ || $storagedFileInfo['updated_at'] < $file['updated_at']) {
169
+ $has_changed = 1;
170
+ } else {
171
+ $has_changed = 0;
172
+ }
173
+
174
+ $data = array(
175
+ 'dir_name' => $localeCode,
176
+ 'file_path' => $file['file_path'],
177
+ 'updated_at' => $file['updated_at'],
178
+ 'has_changed' => $has_changed,
179
+ 'file_exists' => 1
180
+ );
181
+
182
+ $this->_adapter->insertOnDuplicate(
183
+ $this->_resource->getTableName('connector/localization_files_index'),
184
+ $data
185
+ );
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Reset file_exists flag
191
+ */
192
+ public function resetFileExistsFlag() {
193
+ $filesIndexTable = $this->_resource->getTableName('connector/localization_files_index');
194
+ $this->_adapter->query("update {$filesIndexTable} set file_exists = 0");
195
+ }
196
+
197
+ /**
198
+ * Cleanup index stoage
199
+ */
200
+ public function cleanUp() {
201
+ $filesIndexTable = $this->_resource->getTableName('connector/localization_files_index');
202
+ $this->_adapter->query("delete from {$filesIndexTable} where file_exists = 0");
203
+ }
204
+
205
+ }
app/code/community/Smartling/Connector/Model/Localization/Files/Index.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Model_Localization_Files_Index
8
+ extends Mage_Core_Model_Abstract
9
+ {
10
+
11
+ /**
12
+ * set resource model
13
+ *
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/localization_files_index');
17
+ }
18
+
19
+ }
app/code/community/Smartling/Connector/Model/Localization/Files/Observer.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Observer
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Localization_Files_Observer
9
+ {
10
+
11
+ /**
12
+ * Reset has_changed flag for files which was put to queue
13
+ *
14
+ * @param Varien_Event_Observer $object
15
+ */
16
+ public function resetСhangedFlag(Varien_Event_Observer $object){
17
+
18
+ $contentModel = $object->getEvent()->getData('model_instance');
19
+ $content = $object->getEvent()->getData('bulk_submit_content');
20
+
21
+ if( ($contentModel instanceof Smartling_Connector_Model_Content_Localization) === false
22
+ || !is_array($content) ) {
23
+ return false;
24
+ }
25
+
26
+ foreach ($content as $id) {
27
+ $model = Mage::getModel('connector/localization_files_index')->load($id);
28
+ $model->setHasChanged(0);
29
+ $model->save();
30
+ }
31
+
32
+ }
33
+
34
+ /**
35
+ * Reinxed localization files
36
+ *
37
+ * @param Varien_Event_Observer $event
38
+ */
39
+ public function checkFiles(Varien_Event_Observer $event) {
40
+
41
+ $files = Mage::getModel('connector/localization_files');
42
+
43
+ $files->resetFileExistsFlag();
44
+ $files->initIndexedFileList();
45
+ $collection = $files->getAvailableLocales();
46
+
47
+ foreach ($collection as $locale) {
48
+
49
+ $localeCode = $locale->getStoreLocalizationDir();
50
+
51
+ $files->joinFiles('app/locale/' . $localeCode . '/*.csv',
52
+ 'app/design/*/*/default/locale/' . $localeCode . '/*.csv');
53
+
54
+ $files->saveFiles($localeCode);
55
+ }
56
+
57
+ $files->cleanUp();
58
+
59
+ }
60
+
61
+ /**
62
+ * Join files path to content collection
63
+ *
64
+ * @param Varien_Event_Observer $event
65
+ */
66
+ public function joinFilesPath(Varien_Event_Observer $event) {
67
+
68
+ $collection = $event->getEvent()->getData('collection');
69
+ $resource = Mage::getSingleton('core/resource');
70
+
71
+ $collection->getSelect()
72
+ ->joinLeft(array('f' => $resource->getTableName('connector/localization_files_index')),
73
+ 'main_table.origin_content_id = f.id', array('file_path'));
74
+
75
+ }
76
+ }
app/code/community/Smartling/Connector/Model/Projects.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ * List of loaded projects
14
+ * @var array
15
+ */
16
+ protected $_projectsData;
17
+
18
+ /**
19
+ * set resource model
20
+ *
21
+ */
22
+ protected function _construct() {
23
+ $this->_init('connector/projects');
24
+ }
25
+
26
+ /**
27
+ * Return all projects which have locale mapping
28
+ * @param boolean $active
29
+ * @return \Smartling_Connector_Model_Resource_Projects_Collection
30
+ */
31
+ public function getProjectsList($includeInactive = false) {
32
+
33
+ $resource = Mage::getModel('core/resource');
34
+
35
+ $collection = $this->getCollection();
36
+
37
+ // include only active projects
38
+ if($includeInactive == false) {
39
+ $collection->addFieldToFilter('active' , 1);
40
+ }
41
+
42
+ $collection->getSelect()
43
+ ->joinInner( array('pl' => $resource->getTableName('connector/projects_locales')),
44
+ 'main_table.id = pl.parent_id',
45
+ array("parent_id", "store_id", "locale_code")
46
+ )
47
+ ->group('main_table.id');
48
+
49
+ return $collection;
50
+ }
51
+
52
+
53
+ /**
54
+ * Return all projects locales
55
+ * @return array
56
+ */
57
+ public function getProjectsLocales($contentTypeId = '', $content_id = '', $website_ids = array()) {
58
+
59
+ $projects = array();
60
+
61
+ $resource = Mage::getModel('core/resource');
62
+
63
+ $collection = $this->getCollection();
64
+ $collection->addFieldToFilter('active', 1);
65
+ if(sizeof($website_ids)) {
66
+ $collection->addFieldToFilter('website_id', array('in' => $website_ids));
67
+ }
68
+
69
+ $collection->getSelect()
70
+ ->reset(Zend_Db_Select::COLUMNS)
71
+ ->columns(array('name', 'row_id' => 'id', 'website_id'))
72
+ ->joinLeft( array('pl' => $resource->getTableName('connector/projects_locales')), 'main_table.id = pl.parent_id');
73
+
74
+ if($contentTypeId && $content_id) {
75
+ $collection->getSelect()
76
+ ->joinLeft( array('c' => $resource->getTableName('connector/translate_content')),
77
+ 'pl.store_id = c.store_id'
78
+ . ' and c.type = ' . (int)$contentTypeId
79
+ . ' and c.origin_content_id = ' . (int)$content_id,
80
+ array('percent' => 'c.percent')
81
+ );
82
+ }
83
+
84
+ $collection->getSelect()
85
+ ->group('pl.id')
86
+ ->order('main_table.id');
87
+
88
+ foreach ($collection as $project) {
89
+
90
+ if(!isset($projects[$project->getRowId()])) {
91
+ $projects[$project->getRowId()] = array(
92
+ 'id' => $project->getId(),
93
+ 'name' => $project->getName(),
94
+ 'website_id' => $project->getWebsiteId()
95
+ );
96
+ }
97
+
98
+ $localeName = $this->getLocaleTitle($project->getStoreId());
99
+
100
+ $projects[$project->getRowId()]['locales'][$project->getStoreId()] =
101
+ array(
102
+ 'id' => $project->getStoreId(),
103
+ 'project_identity' => $project->getId(),
104
+ 'name' => $localeName,
105
+ 'percent' => $project->getPercent()
106
+ );
107
+
108
+ }
109
+
110
+ return $projects;
111
+ }
112
+
113
+ /**
114
+ *
115
+ * @param int $storeId
116
+ * @return string
117
+ */
118
+ public function getLocaleTitle($storeId) {
119
+ $localeName = Mage::app()->getStore($storeId)->getFrontendName()
120
+ . ' (' . Mage::app()->getStore($storeId)->getName() . ')';
121
+
122
+ return $localeName;
123
+ }
124
+
125
+ /**
126
+ * Get project data
127
+ * @param int $project_id
128
+ * @return boolean|\Smartling_Connector_Model_Resource_Projects_Collection
129
+ */
130
+ public function getProjectData($project_id) {
131
+ if(isset($this->_projectsData[$project_id])) {
132
+ return $this->_projectsData[$project_id];
133
+ }
134
+
135
+ $collection = $this->getCollection();
136
+ $collection->addFieldToFilter('id' , $project_id);
137
+
138
+ if($collection->getSize()) {
139
+ $this->_projectsData[$project_id] = $collection;
140
+ return $collection;
141
+ } else {
142
+ return false;
143
+ }
144
+ }
145
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Projects filter abstract class
5
+ *
6
+ * @author Smartling
7
+ */
8
+ abstract class Smartling_Connector_Model_Projects_Filter
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+ abstract public function getAvailableProjects($fiter_id);
12
+
13
+ /**
14
+ *
15
+ * @param Mage_Core_Model_Resource_Db_Collection_Abstract $collection
16
+ * @return array
17
+ */
18
+ protected function getProjectList($collection) {
19
+
20
+ $projects = array();
21
+
22
+ foreach ($collection as $project) {
23
+
24
+ if(!isset($projects[$project->getRowId()])) {
25
+ $projects[$project->getRowId()] = array(
26
+ 'id' => $project->getId(),
27
+ 'name' => $project->getName(),
28
+ 'website_id' => $project->getWebsiteId()
29
+ );
30
+ }
31
+
32
+ $localeName = Mage::app()->getStore($project->getStoreId())->getFrontendName()
33
+ . ' (' . Mage::app()->getStore($project->getStoreId())->getName() . ')';
34
+
35
+ $projects[$project->getRowId()]['locales'][$project->getStoreId()] =
36
+ array(
37
+ 'id' => $project->getStoreId(),
38
+ 'project_identity' => $project->getId(),
39
+ 'name' => $localeName,
40
+ );
41
+
42
+ }
43
+
44
+
45
+ return $projects;
46
+ }
47
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/Attribute.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by products relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_Attribute
9
+ extends Smartling_Connector_Model_Projects_Filter_CmsPage
10
+ {
11
+
12
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/Category.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by categories relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_Category
9
+ extends Smartling_Connector_Model_Projects_Filter
10
+ {
11
+ /**
12
+ *
13
+ * @param int $store_group_id
14
+ * @return array
15
+ */
16
+ public function getAvailableProjects($store_group_id) {
17
+
18
+ $resource = Mage::getModel('core/resource');
19
+ $collection = Mage::getModel('core/store_group')->getCollection();
20
+ $collection->addFieldToFilter('main_table.group_id', $store_group_id);
21
+
22
+ $collection->getSelect()
23
+ ->joinInner( array('s' => $resource->getTableName('core/store')),
24
+ 'main_table.group_id = ' . (int)$store_group_id
25
+ . ' and s.group_id = main_table.group_id')
26
+ ->joinInner( array('pl' => $resource->getTableName('connector/projects_locales')),
27
+ 'pl.store_id = s.store_id', array('id'))
28
+ ->joinInner( array('p' => $resource->getTableName('connector/projects')),
29
+ 'p.id = pl.parent_id')
30
+ ->reset(Zend_Db_Select::COLUMNS)
31
+ ->columns(array('p.name',
32
+ 'row_id' => 'p.id',
33
+ 'id' => 'pl.id',
34
+ 'p.website_id',
35
+ 's.store_id'
36
+ ));
37
+
38
+ $options = $this->getProjectList($collection);
39
+
40
+ return $options;
41
+ }
42
+
43
+ /**
44
+ *
45
+ * @return string
46
+ */
47
+ public function getMessageOnEmptyRequest() {
48
+ return Mage::helper('connector')->__('Please select store to see list of available profiles');
49
+ }
50
+
51
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/CmsBlock.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by products relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_CmsBlock
9
+ extends Smartling_Connector_Model_Projects_Filter_CmsPage
10
+ {
11
+
12
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/CmsPage.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by products relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_CmsPage
9
+ extends Smartling_Connector_Model_Projects_Filter
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @param int $website_id
15
+ * @return array
16
+ */
17
+ public function getAvailableProjects($website_id) {
18
+
19
+ $projects = array();
20
+
21
+ $resource = Mage::getModel('core/resource');
22
+
23
+ $collection = Mage::getModel('connector/projects')->getCollection();
24
+ $collection->addFieldToFilter('active', 1);
25
+
26
+ $collection->getSelect()
27
+ ->reset(Zend_Db_Select::COLUMNS)
28
+ ->columns(array('name', 'row_id' => 'id', 'website_id'))
29
+ ->joinLeft( array('pl' => $resource->getTableName('connector/projects_locales')), 'main_table.id = pl.parent_id');
30
+
31
+ $collection->getSelect()
32
+ ->group('pl.id')
33
+ ->order('main_table.id');
34
+
35
+ $projects = $this->getProjectList($collection);
36
+
37
+ return $projects;
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @return string
43
+ */
44
+ public function getMessageOnEmptyRequest() {
45
+ return '';
46
+ }
47
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/Localization.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by products relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_Localization
9
+ extends Smartling_Connector_Model_Projects_Filter
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @param int $website_id
15
+ * @return array
16
+ */
17
+ public function getAvailableProjects($website_id) {
18
+
19
+ $resource = Mage::getModel('core/resource');
20
+ $storeViewTableName = $resource->getTableName('core_store');
21
+ $storeGroupTableName = $resource->getTableName('core_store_group');
22
+ $localizationFilesIndexTableName = $resource->getTableName('connector/localization_files_index');
23
+
24
+ $collection = Mage::getModel('connector/projects')->getCollection();
25
+ $collection->addFieldToFilter('active', 1);
26
+
27
+ $collection->getSelect()
28
+ ->reset(Zend_Db_Select::COLUMNS)
29
+ ->columns(array('name', 'row_id' => 'id', 'website_id'))
30
+ ->joinLeft( array('pl' => $resource->getTableName('connector/projects_locales')), 'main_table.id = pl.parent_id')
31
+ ->joinInner(array('cs' => $storeViewTableName),
32
+ 'pl.store_id = cs.store_id',
33
+ array())
34
+ ->joinInner(array('csg' => $storeGroupTableName),
35
+ 'cs.group_id = csg.default_store_id',
36
+ array())
37
+ ->joinInner(array('cs2' => $storeViewTableName),
38
+ 'csg.default_store_id = cs2.store_id',
39
+ array())
40
+ ->joinInner(array('lfi' => $localizationFilesIndexTableName),
41
+ 'cs2.store_localization_dir = lfi.dir_name',
42
+ array())
43
+ ->group('pl.id')
44
+ ->order('main_table.id');
45
+
46
+ $projects = $this->getProjectList($collection);
47
+
48
+ return $projects;
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @return string
54
+ */
55
+ public function getMessageOnEmptyRequest() {
56
+ return '';
57
+ }
58
+ }
app/code/community/Smartling/Connector/Model/Projects/Filter/Product.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Filter projects by products relations
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Filter_Product
9
+ extends Smartling_Connector_Model_Projects_Filter
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @param int $website_id
15
+ * @return array
16
+ */
17
+ public function getAvailableProjects($website_id) {
18
+
19
+ $projects = array();
20
+
21
+ $resource = Mage::getModel('core/resource');
22
+
23
+ $collection = Mage::getModel('connector/projects')->getCollection();
24
+ $collection->addFieldToFilter('active', 1);
25
+ $collection->addFieldToFilter('website_id', array('eq' => $website_id));
26
+
27
+ $collection->getSelect()
28
+ ->reset(Zend_Db_Select::COLUMNS)
29
+ ->columns(array('name', 'row_id' => 'id', 'website_id'))
30
+ ->joinLeft( array('pl' => $resource->getTableName('connector/projects_locales')), 'main_table.id = pl.parent_id');
31
+
32
+ $collection->getSelect()
33
+ ->group('pl.id')
34
+ ->order('main_table.id');
35
+
36
+ $projects = $this->getProjectList($collection);
37
+
38
+ return $projects;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @return string
44
+ */
45
+ public function getMessageOnEmptyRequest() {
46
+ return Mage::helper('connector')->__('Please select website to see list of available profiles');
47
+ }
48
+ }
app/code/community/Smartling/Connector/Model/Projects/Locales.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Projects_Locales
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ * set resource model
14
+ *
15
+ */
16
+ protected function _construct() {
17
+ $this->_init('connector/projects_locales');
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @param int $store_id
23
+ * @return string
24
+ */
25
+ public function getLocaleCodeByStoreId($store_id) {
26
+
27
+ $collection = $this->getCollection()
28
+ ->addFieldToFilter('store_id', $store_id);
29
+
30
+ $data = $collection->getFirstItem();
31
+
32
+ return $data['locale_code'];
33
+
34
+ }
35
+
36
+ /**
37
+ *
38
+ * @param mixed $stores_id
39
+ * @return array|int
40
+ */
41
+ public function getLocaleCodes($stores_id) {
42
+
43
+ $locale_code = '';
44
+
45
+ $collection = $this->getCollection();
46
+ if(!is_array($stores_id)) {
47
+
48
+ $collection->addFieldToFilter('store_id', $stores_id);
49
+ $data = $collection->getFirstItem();
50
+ $locale_code = $data['locale_code'];
51
+
52
+ } else {
53
+
54
+ $locale_code = array();
55
+ $collection->addFieldToFilter('store_id', array('in' => $stores_id));
56
+ foreach ($collection as $item) {
57
+ $locale_code[] = $item->getLocaleCode();
58
+ }
59
+ }
60
+
61
+ return $locale_code;
62
+
63
+ }
64
+
65
+ }
app/code/community/Smartling/Connector/Model/Request.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Request
5
+ *
6
+ * @author snail
7
+ */
8
+ class Smartling_Connector_Model_Request
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @var array
15
+ */
16
+ protected $_headers = array();
17
+
18
+ /**
19
+ *
20
+ * @var Zend_Http_Client_Adapter_Socket | null
21
+ */
22
+ protected $_client = null;
23
+
24
+ /**
25
+ *
26
+ * @var Zend_Http_Uri | null
27
+ */
28
+ protected $_uri = null;
29
+
30
+ /**
31
+ *
32
+ */
33
+ protected $_port = null;
34
+
35
+ /**
36
+ *
37
+ * @var array
38
+ */
39
+ protected $_post = array();
40
+
41
+ /**
42
+ *
43
+ * @var string
44
+ */
45
+ protected $_method = Zend_Http_Client::GET;
46
+
47
+ /**
48
+ *
49
+ * @param string $uri
50
+ */
51
+ public function __construct() {
52
+ parent::__construct();
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @param array $headers
58
+ * @return \Smartling_Connector_Model_Request
59
+ */
60
+ public function setHeaders($headers = array()){
61
+ $this->_headers = array_merge($this->_headers, $headers);
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ *
67
+ * @param array $config
68
+ */
69
+ public function initConnection($config = array()){
70
+ $this->_client = new Zend_Http_Client_Adapter_Socket();
71
+ if (!empty($config)){
72
+ $this->_client->setConfig($config);
73
+ }
74
+ $this->_client->connect($this->_uri->getHost(), $this->_uri->getPort());
75
+
76
+ }
77
+
78
+ /**
79
+ *
80
+ * @param array $post
81
+ * @return \Smartling_Connector_Model_Request
82
+ */
83
+ public function setPostParams($post = array()){
84
+ $this->_post = $post;
85
+ return $this;
86
+ }
87
+
88
+ /**
89
+ *
90
+ * @param string $method
91
+ * @return \Smartling_Connector_Model_Request
92
+ */
93
+ public function setMethod($method){
94
+ $this->_method = $method;
95
+ return $this;
96
+ }
97
+
98
+ /**
99
+ *
100
+ * @param string $uri
101
+ * @return \Smartling_Connector_Model_Request
102
+ */
103
+ public function setUri($uri){
104
+ $this->_uri = Zend_Uri_Http::factory($uri);
105
+ $this->_setPort($uri);
106
+ return $this;
107
+ }
108
+
109
+ /**
110
+ * send request
111
+ *
112
+ * @return void
113
+ */
114
+ public function sendRequest(){
115
+ $this->_prepareRequest();
116
+ $body = '';
117
+ if (!empty($this->_post)){
118
+ $body = http_build_query($this->_post);
119
+ $this->setHeaders(array('Content-Length' => strlen($body)));
120
+ }
121
+ $this->setHeaders(array('Connection' => 'Close'));
122
+ $this->_client->write($this->_method, $this->_uri, '1.1', $this->_headers, $body);
123
+ }
124
+
125
+ public function getResponse(){
126
+ return $this->_client->read();
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @return string
132
+ */
133
+ protected function _getCookie(){
134
+ $webSites = Mage::app()->getWebsites();
135
+ $code = $webSites[1]->getCode();
136
+ $session = Mage::getSingleton("customer/session");
137
+ $session->init('customer_' . $code);
138
+ return session_id();
139
+ }
140
+
141
+ /**
142
+ * set default headers
143
+ */
144
+ protected function _prepareRequest(){
145
+ $cookie = $this->_getCookie();
146
+ $headers = array('Host' => $this->_uri->getHost(),
147
+ 'Cookie' => "adminhtml={$cookie}",
148
+ 'Cntent-type' => 'application/x-www-form-urlencoded; charset=utf-8',
149
+ 'Accept' => '*/*;q=0.5',
150
+ );
151
+ $this->setHeaders($headers);
152
+ }
153
+
154
+ /**
155
+ * Set port if not defined
156
+ *
157
+ * @throws Mage_Exception
158
+ */
159
+ protected function _setPort($uri){
160
+ if (!$this->_uri->getPort()) {
161
+ $port = (parse_url($uri, PHP_URL_SCHEME) == 'https') ? 443 : 80;
162
+ $this->_uri->setPort($port);
163
+ }
164
+ }
165
+ }
app/code/community/Smartling/Connector/Model/Resource/Content.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Content
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/translate_content', 'content_id');
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @param array $data
22
+ */
23
+ public function createNewTranslationQueue($data){
24
+ $table = $this->getMainTable();
25
+ $result = $this->_getWriteAdapter()->insertMultiple($table, $data);
26
+ return $result;
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @param array $data
32
+ * @param string $locales
33
+ * @return array
34
+ */
35
+ public function findContent($data, $locales) {
36
+ $select = $this->_getReadAdapter()->select()
37
+ ->from(array('ct' => $this->getMainTable()))
38
+ ->where('ct.origin_content_id = ?', $data['origin_content_id'])
39
+ ->where('ct.locale = ?', $locales)
40
+ ->where('ct.type = ?', $data['type']);
41
+ $select->reset(Zend_Db_Select::COLUMNS)
42
+ ->columns(array('ct.filename', 'content_id'))
43
+ ->order('ct.content_id DESC')
44
+ ->limit(1);
45
+ return $this->_getReadAdapter()->fetchRow($select);
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param string $locale
51
+ * @param array $data
52
+ * @return int
53
+ */
54
+ public function addSingleItem($store_id, $data, $force = false) {
55
+
56
+ if(!$force) {
57
+ $locale = Mage::getSingleton('connector/projects_locales')->getLocaleCodeByStoreId($store_id);
58
+
59
+ if(!$locale) {
60
+ return 0;
61
+ }
62
+ }
63
+
64
+ $additionalData = array (
65
+ 'store_id' => $store_id,
66
+ 'submitter' => Mage::helper('connector')->getSubmitter(),
67
+ 'percent' => floatval(0.00),
68
+ 'status' => Smartling_Connector_Model_Content::CONTENT_STATUS_NEW,
69
+ );
70
+
71
+ $data = array_merge($additionalData, $data);
72
+
73
+ $fields = array ('status', 'percent', 'submitter');
74
+ $table = $this->getMainTable();
75
+ $result = $this->_getWriteAdapter()->insertOnDuplicate($table, $data, $fields);
76
+ return $result;
77
+ }
78
+
79
+ /**
80
+ * Save object object data
81
+ *
82
+ * @param Mage_Core_Model_Abstract $object
83
+ * @return Mage_Core_Model_Resource_Db_Abstract
84
+ */
85
+ public function save(Mage_Core_Model_Abstract $object)
86
+ {
87
+ if ($object->isDeleted()) {
88
+ return $this->delete($object);
89
+ }
90
+
91
+ $this->_serializeFields($object);
92
+ $this->_beforeSave($object);
93
+ $this->_checkUnique($object);
94
+ if (!is_null($object->getId()) && (!$this->_useIsObjectNew || !$object->isObjectNew())) {
95
+
96
+ $originContentId = $object->getOriginContentId();
97
+ $projectId = $object->getProjectId();
98
+
99
+ if(strstr($object->getLocales(), ',') && isset($originContentId)) {
100
+ $condition[] = $this->_getWriteAdapter()->quoteInto('origin_content_id=?', $object->getOriginContentId());
101
+ if($projectId) {
102
+ $condition[] = $this->_getWriteAdapter()->quoteInto('project_id=?', $object->getProjectId());
103
+ }
104
+ } else {
105
+ $condition = $this->_getWriteAdapter()->quoteInto($this->getIdFieldName().'=?', $object->getId());
106
+ }
107
+
108
+ /**
109
+ * Not auto increment primary key support
110
+ */
111
+ if ($this->_isPkAutoIncrement) {
112
+ $data = $this->_prepareDataForSave($object);
113
+ unset($data[$this->getIdFieldName()]);
114
+ $this->_getWriteAdapter()->update($this->getMainTable(), $data, $condition);
115
+ } else {
116
+ $select = $this->_getWriteAdapter()->select()
117
+ ->from($this->getMainTable(), array($this->getIdFieldName()))
118
+ ->where($condition);
119
+
120
+ if ($this->_getWriteAdapter()->fetchOne($select) !== false) {
121
+ $data = $this->_prepareDataForSave($object);
122
+ unset($data[$this->getIdFieldName()]);
123
+ if (!empty($data)) {
124
+ $this->_getWriteAdapter()->update($this->getMainTable(), $data, $condition);
125
+ }
126
+ } else {
127
+ $this->_getWriteAdapter()->insert($this->getMainTable(), $this->_prepareDataForSave($object));
128
+ }
129
+ }
130
+ } else {
131
+ $bind = $this->_prepareDataForSave($object);
132
+ if ($this->_isPkAutoIncrement) {
133
+ unset($bind[$this->getIdFieldName()]);
134
+ }
135
+ $this->_getWriteAdapter()->insert($this->getMainTable(), $bind);
136
+
137
+ $object->setId($this->_getWriteAdapter()->lastInsertId($this->getMainTable()));
138
+
139
+ if ($this->_useIsObjectNew) {
140
+ $object->isObjectNew(false);
141
+ }
142
+ }
143
+
144
+ $this->unserializeFields($object);
145
+ $this->_afterSave($object);
146
+
147
+ return $this;
148
+ }
149
+
150
+ }
app/code/community/Smartling/Connector/Model/Resource/Content/Collection.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Content_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+
12
+ protected function _construct() {
13
+ $this->_init('connector/content');
14
+ }
15
+
16
+ /**
17
+ *
18
+ * @param int $content_id
19
+ * @return \Smartling_Connector_Model_Resource_Content_Collection
20
+ */
21
+ public function addIndentifyToFilter($content_id)
22
+ {
23
+ $this->addFieldToFilter('content_id', $content_id);
24
+
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ *
30
+ * @param int $content_id
31
+ * @return \Smartling_Connector_Model_Resource_Content_Collection
32
+ */
33
+ public function addUniqueByParams($origin_content_id, $project_id, $storeId)
34
+ {
35
+ $this->addFilterToMap('origin_content_id', 'main_table.origin_content_id')
36
+ ->addFilterToMap('project_id', 'main_table.project_id')
37
+ ->addFilterToMap('store_id', 'main_table.store_id');
38
+
39
+ $this->addFieldToFilter('origin_content_id', $origin_content_id)
40
+ ->addFieldToFilter('project_id', $project_id)
41
+ ->addFieldToFilter('store_id', $storeId);
42
+
43
+ return $this;
44
+ }
45
+
46
+ /**
47
+ * Join additional tables to collection data
48
+ * @return \Smartling_Connector_Model_Resource_Content_Collection
49
+ */
50
+ public function joinAdditionalDetails()
51
+ {
52
+ $resource = Mage::getModel('core/resource');
53
+
54
+ $this->getSelect()
55
+ ->joinInner(
56
+ array('p' => $resource->getTableName('connector/projects')),
57
+ 'main_table.project_id = p.id',
58
+ array('project_id' => 'id',
59
+ 'project_code' => 'project_id',
60
+ 'api_key'=> 'key',
61
+ 'api_url', 'retrieval_type')
62
+ )
63
+ ->joinInner(
64
+ array('pl' => $resource->getTableName('connector/projects_locales')),
65
+ 'main_table.project_id = pl.parent_id and main_table.store_id = pl.store_id ',
66
+ array('locale' => 'locale_code')
67
+ )
68
+ ->joinInner(
69
+ array('ct' => $resource->getTableName('connector/content_types')),
70
+ 'main_table.type = ct.type_id',
71
+ array('model_class' => 'model')
72
+ );
73
+ return $this;
74
+ }
75
+ }
app/code/community/Smartling/Connector/Model/Resource/Content/Types.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Content_Types
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and table id
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/content_types', 'type_id');
17
+ }
18
+ }
19
+
app/code/community/Smartling/Connector/Model/Resource/Content/Types/Collection.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Content_Types_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+
12
+ }
app/code/community/Smartling/Connector/Model/Resource/Localization/Files/Index.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Model_Resource_Localization_Files_Index
8
+ extends Mage_Core_Model_Resource_Db_Abstract
9
+ {
10
+
11
+ /**
12
+ * define table and
13
+ */
14
+ protected function _construct() {
15
+ $this->_init('connector/localization_files_index', 'id');
16
+ }
17
+
18
+ }
app/code/community/Smartling/Connector/Model/Resource/Localization/Files/Index/Collection.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ * @author Smartling
6
+ */
7
+ class Smartling_Connector_Model_Resource_Localization_Files_Index_Collection
8
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
9
+ {
10
+
11
+ protected function _construct() {
12
+ $this->_init('connector/localization_files_index');
13
+ }
14
+ }
app/code/community/Smartling/Connector/Model/Resource/Log/Collection.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Model_Resource_Log_Collection
4
+ extends Varien_Data_Collection
5
+ {
6
+ /**
7
+ *
8
+ * @var array
9
+ */
10
+ protected $_include_only = array();
11
+
12
+ /**
13
+ *
14
+ * @var boolean
15
+ */
16
+ protected $_dataLoaded = false;
17
+
18
+ /**
19
+ *
20
+ * @var array
21
+ */
22
+ protected $_collectionItemsUnsorted = array();
23
+
24
+ /**
25
+ * Load data
26
+ *
27
+ * @param boolean $printQuery
28
+ * @param boolean $logQuery
29
+ * @return \Smartling_Connector_Model_Resource_Log_Collection
30
+ */
31
+ public function loadData($printQuery = false, $logQuery = false) {
32
+
33
+ $_pageSize = $this->getPageSize();
34
+ $_currPage = $this->getCurPage();
35
+ $logFile = Mage::getBaseDir('var') . DS . 'log' . DS . Mage::getStoreConfig('dev/smartling/log_file');
36
+
37
+ if ($this->_dataLoaded || !is_file($logFile) ) {
38
+ return $this;
39
+ }
40
+
41
+ $content = file($logFile);
42
+ $_itemsCount = 0;
43
+
44
+ if($content != false && sizeof($content)) {
45
+
46
+ $_startIndex = ($_currPage - 1) * $_pageSize;
47
+
48
+ $_itemsCount = count($content);
49
+
50
+ if ($_startIndex > $_itemsCount) {
51
+ $_startIndex = (int)($_itemsCount / $_pageSize) * $_pageSize;
52
+ }
53
+
54
+ $inc = $rowCount = $_addedCount = $_index = 0;
55
+ $segments = $row = array();
56
+
57
+ $collectionIndex = $currentIndex = 0;
58
+
59
+ foreach ($content as $row) {
60
+
61
+ $inc++;
62
+ $rowCount++;
63
+
64
+ preg_match_all('/(^.+) ?(INFO|DEBUG|ERR) \(\d+\)\: (.+)$/mi', $row, $segments);
65
+ if(isset($segments[2][0])) {
66
+ $const = constant('Zend_log::' . $segments[2][0]);
67
+ }
68
+
69
+ $levels = Mage::helper('connector')->getLogLevels();
70
+
71
+ $message = '';
72
+ if(isset($segments[3][0])) {
73
+ $message = $segments[3][0];
74
+ }
75
+
76
+ if(isset($segments[2][0]) && strlen($segments[2][0])) { // if log level has found
77
+ $collectionIndex++;
78
+ }
79
+
80
+ $time = '';
81
+ if(isset($segments[1][0])) {
82
+ $time = Mage::helper('core')->formatDate($segments[1][0], 'medium', true);
83
+ }
84
+
85
+ $item = array('id' => $rowCount,
86
+ 'time' => $time,
87
+ 'level' => $levels[$const],
88
+ 'message' => $message);
89
+
90
+ if(sizeof($segments)) {
91
+
92
+ if($currentIndex == $collectionIndex) {
93
+ $this->_collectionItemsUnsorted[$collectionIndex]['message'] .= $row;
94
+ } else {
95
+ $this->_collectionItemsUnsorted[$collectionIndex] = $item;
96
+ $rowCount++;
97
+ }
98
+ }
99
+
100
+ $currentIndex = $collectionIndex;
101
+ $message = '';
102
+ $item = array();
103
+ $segments = array();
104
+
105
+ }
106
+
107
+ if(sizeof($this->_collectionItemsUnsorted)) {
108
+ $finalArray = array_reverse($this->_collectionItemsUnsorted);
109
+
110
+ foreach ($finalArray as $item) {
111
+
112
+ if ($_index++ < $_startIndex) {
113
+ continue;
114
+ }
115
+
116
+ if (++$_addedCount > $_pageSize) {
117
+ break;
118
+ }
119
+
120
+ $varienObject = new Varien_Object();
121
+ $varienObject->setData($item);
122
+ $this->addItem($varienObject);
123
+ }
124
+ }
125
+ }
126
+
127
+ $this->_totalRecords = count($finalArray);
128
+
129
+ $this->_dataLoaded = true;
130
+ return $this;
131
+
132
+ }
133
+
134
+ public function getCurPage($displacement = 0) {
135
+ return (int)$this->_curPage;
136
+ }
137
+
138
+ }
app/code/community/Smartling/Connector/Model/Resource/Projects.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Projects
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/projects', 'id');
17
+ }
18
+
19
+ }
app/code/community/Smartling/Connector/Model/Resource/Projects/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Projects_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+
12
+ protected function _construct() {
13
+ $this->_init('connector/projects');
14
+ }
15
+ }
app/code/community/Smartling/Connector/Model/Resource/Projects/Locales.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Projects_Locales
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/projects_locales', 'id');
17
+ }
18
+
19
+ }
app/code/community/Smartling/Connector/Model/Resource/Projects/Locales/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Projects_Locales_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+
12
+ protected function _construct() {
13
+ $this->_init('connector/projects_locales');
14
+ }
15
+ }
app/code/community/Smartling/Connector/Model/Resource/Translate/Attributes.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Translate_Attributes
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and table id
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/translate_attributes', 'id');
17
+ }
18
+
19
+ }
20
+
app/code/community/Smartling/Connector/Model/Resource/Translate/Attributes/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Translate_Attributes_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+ protected function _construct()
12
+ {
13
+ $this->_init('connector/translate_attributes');
14
+ }
15
+ }
app/code/community/Smartling/Connector/Model/Resource/Translate/Fields.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Translate_Fields
9
+ extends Mage_Core_Model_Resource_Db_Abstract
10
+ {
11
+
12
+ /**
13
+ * define table and table id
14
+ */
15
+ protected function _construct() {
16
+ $this->_init('connector/translate_fields', 'id');
17
+ }
18
+
19
+ }
20
+
app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Collection
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Resource_Translate_Fields_Collection
9
+ extends Mage_Core_Model_Resource_Db_Collection_Abstract
10
+ {
11
+ protected function _construct()
12
+ {
13
+ $this->_init('connector/translate_fields');
14
+ }
15
+ }
app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Block/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Smartling_Connector_Model_Resource_Translate_Fields_List_Block_Collection
3
+ extends Smartling_Connector_Model_Resource_Translate_Fields_List_Collection
4
+ {
5
+ function __construct() {
6
+
7
+ $this->_code = 'block';
8
+ $this->_typeName = 'cmsBlock';
9
+
10
+ $this->_fields = Mage::helper('connector')->getFields('cms_' . $this->_code);
11
+
12
+ parent::__construct();
13
+ }
14
+
15
+ }
app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Collection.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Smartling_Connector_Model_Resource_Translate_Fields_List_Collection
3
+ extends Varien_Data_Collection
4
+ {
5
+ /**
6
+ *
7
+ * @var array - field list
8
+ */
9
+ protected $_fields = array();
10
+
11
+ /**
12
+ *
13
+ * @var array - field description mapping
14
+ */
15
+ protected $_fieldsDesctriptionMapping = array();
16
+
17
+ /**
18
+ *
19
+ * @var string - module code
20
+ */
21
+ protected $_code;
22
+
23
+ /**
24
+ *
25
+ * @var string - Smartling type name
26
+ */
27
+ protected $_typeName;
28
+
29
+ /**
30
+ * List of translatable fileds
31
+ * @var array
32
+ */
33
+ protected $_translatableFields = array();
34
+
35
+ /**
36
+ *
37
+ * @param string $table_name
38
+ */
39
+ function __construct($table_name = '') {
40
+
41
+ if($table_name) {
42
+ $this->_fields = Mage::helper('connector')->getFields($table_name);
43
+ }
44
+
45
+ $this->_fieldsDesctriptionMapping = array(
46
+ 'title' => Mage::helper('cms')->__('Page Title'),
47
+ 'content_heading' => Mage::helper('cms')->__('Content Heading'),
48
+ 'content' => Mage::helper('cms')->__('Content'),
49
+ 'meta_keywords' => Mage::helper('cms')->__('Meta Keywords'),
50
+ 'meta_description' => Mage::helper('cms')->__('Meta Description')
51
+ );
52
+
53
+ $entityTypeId = $this->getContentTypeId();
54
+ $collection = Mage::getModel('connector/translate_fields')->getCollection()
55
+ ->addFieldToFilter('entity_type_id', array('eq' => $entityTypeId));
56
+
57
+ foreach ($collection as $item) {
58
+ $this->_translatableFields[] = $item->getFieldName();
59
+ }
60
+
61
+
62
+ $this->setItems();
63
+ }
64
+
65
+ /**
66
+ * Fill collection
67
+ */
68
+ protected function setItems() {
69
+
70
+ $ignoreFields = Mage::getStoreConfig('connector/translate_attributes/cms_' . $this->_code);
71
+ if($ignoreFields) {
72
+ $systemFields = array_keys($ignoreFields);
73
+ } else {
74
+ $systemFields = array();
75
+ }
76
+
77
+ if(sizeof($this->_fields)) {
78
+ foreach ($this->_fields as $item) {
79
+
80
+ if(in_array($item, $systemFields)) {
81
+ continue;
82
+ }
83
+
84
+ $varienObject = new Varien_Object();
85
+ $row = array('id' => $item,
86
+ 'text' => $this->getDescription($item),
87
+ 'is_attached' => in_array($item, $this->_translatableFields),
88
+ 'is_html_allowed_on_front' => in_array($item, $this->_translatableFields),
89
+ );
90
+
91
+ $varienObject->setData($row);
92
+ $this->addItem($varienObject);
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @param string $key
100
+ * @return string
101
+ */
102
+ public function getDescription($key) {
103
+ return $this->_fieldsDesctriptionMapping[$key];
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @return int
109
+ */
110
+ public function getContentTypeId() {
111
+ $type = Mage::getModel('connector/content_types')->getTypeDetails($this->_typeName);
112
+ return $type->getTypeId();
113
+ }
114
+
115
+ /**
116
+ *
117
+ * @param string $field
118
+ * @param string|int $value
119
+ */
120
+ public function includeWithValue($field, $value) {
121
+ foreach ($this->getItems() as $id=>$item) {
122
+ if($item->getData($field) != $value) {
123
+ $this->removeItemByKey($id);
124
+ }
125
+ }
126
+ }
127
+ }
app/code/community/Smartling/Connector/Model/Resource/Translate/Fields/List/Page/Collection.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Smartling_Connector_Model_Resource_Translate_Fields_List_Page_Collection
4
+ extends Smartling_Connector_Model_Resource_Translate_Fields_List_Collection
5
+ {
6
+ function __construct() {
7
+ $this->_code = 'page';
8
+ $this->_typeName = 'cmsPage';
9
+
10
+ $this->_fields = Mage::helper('connector')->getFields('cms_' . $this->_code);
11
+
12
+ parent::__construct();
13
+ }
14
+ }
app/code/community/Smartling/Connector/Model/Service.php ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CallUpload
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Service
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+ /**
12
+ *
13
+ * @var string
14
+ */
15
+ protected $_uri = '';
16
+
17
+ /**
18
+ *
19
+ * @var int
20
+ */
21
+ protected $_step = 5;
22
+
23
+ /**
24
+ *
25
+ */
26
+ protected $_maxThreads;
27
+
28
+ /**
29
+ * Lock file name
30
+ */
31
+ protected $_lockFileName = 'smartling_check_status_process.lock';
32
+
33
+ /**
34
+ * Check status lock status
35
+ * @var null|boolean
36
+ */
37
+ protected $_isLocked = null;
38
+
39
+ /**
40
+ *
41
+ * @param string | null $uri
42
+ */
43
+ public function __construct($uri = '') {
44
+ if ($uri != '') {
45
+ $this->_uri = $uri;
46
+ }
47
+
48
+ $this->_maxThreads = Mage::getStoreConfig('connector/max_threads');
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @param string $uri
54
+ * @return \Smartling_Connector_Model_CallUpload
55
+ */
56
+ public function setUri($uri) {
57
+ $this->_uri = $uri;
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * run upload process
63
+ *
64
+ * @return bool
65
+ */
66
+ public function callUpload($content_id = 0) {
67
+
68
+ /** @var $contentType Smartling_Connector_Model_Content */
69
+ $contentType = Mage::getModel('connector/content');
70
+ $collection = $contentType->getNewItems();
71
+
72
+ $errors = array();
73
+
74
+ if(is_numeric($content_id) && $content_id) {
75
+ $collection->addFieldToFilter('content_id', $content_id);
76
+ }
77
+
78
+ if (!$collection->getSize()) {
79
+ return false;
80
+ }
81
+
82
+ foreach($collection as $item) {
83
+
84
+ /** @var $contentModel Smartling_Connector_Model_Content_Abstract */
85
+ $contentModel = Mage::getModel($item['model']);
86
+
87
+ try {
88
+
89
+ if(($contentModel instanceof Smartling_Connector_Model_Content_Abstract) == false) {
90
+ Mage::throwException("Application error. Model '{$item['model']}' does not of required type");
91
+ }
92
+
93
+ $instanceModel = $contentModel->getContentTypeEntityModel()
94
+ ->load($item['origin_content_id']);
95
+
96
+ if ($instanceModel->getId()) {
97
+ $content = $contentModel->createTranslateContent($instanceModel, $item['project_id'], $item['source_store_id']);
98
+
99
+ if(!$content || $content == '-1') {
100
+
101
+ $errMessage = "Upload content: Content is empty."
102
+ . " Content type: {$contentModel->getContentTypeCode()}."
103
+ . " Content id: {$instanceModel->getId()}";
104
+
105
+ Mage::throwException($errMessage);
106
+ }
107
+
108
+ $fileUri = ($item['filename']) ? $item['filename'] : $contentModel->getFileUri();
109
+
110
+ $responseSuccessStatus = $contentModel->uploadContent($content, $fileUri, $item);
111
+
112
+ } else {
113
+ $fileUri = $item['filename'];
114
+ }
115
+
116
+ if(!$item['filename']) {
117
+ $item['filename'] = $fileUri;
118
+ }
119
+
120
+ /**
121
+ * if successfully uploaded - update data in db about content item
122
+ */
123
+ if ($responseSuccessStatus) {
124
+ /**
125
+ * write event to logger
126
+ */
127
+ $message = Mage::helper('connector')->__('File "%s" for locale %s has been uploded',
128
+ $item['filename'],
129
+ $item['locales']);
130
+
131
+ Mage::helper('connector')->log($message, Zend_log::INFO);
132
+
133
+ $status = Smartling_Connector_Model_Content::CONTENT_STATUS_PROCESS;
134
+ $updateData = array('content_id' => $item['content_id'],
135
+ 'filename' => $item['filename'],
136
+ 'status' => $status,
137
+ 'content_title' => $contentModel->getContentTitle(),
138
+ 'locales' => $item['locales'],
139
+ 'origin_content_id' => $item['origin_content_id'],
140
+ 'project_id' => $item['project_id']
141
+ );
142
+ $contentType->setData($updateData);
143
+ try {
144
+ $contentType->save();
145
+ } catch (Mage_Exception $e){
146
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
147
+ Mage::throwException($e->getMessage());
148
+ }
149
+
150
+ } else {
151
+
152
+ $message = Mage::helper('connector')->__('Unable to upload "%s" for locale %s',
153
+ $contentModel->getFileUri(),
154
+ $item['locale']
155
+ );
156
+
157
+ Mage::helper('connector')->log($message, Zend_log::ERR);
158
+ Mage::throwException($message);
159
+ }
160
+
161
+ } catch (Mage_Core_Exception $e) {
162
+ $errors[] = $e->getMessage();
163
+ } catch (Exception $e) {
164
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
165
+ }
166
+
167
+ gc_collect_cycles();
168
+ flush();
169
+ }
170
+
171
+ if(sizeof($errors)) {
172
+ Mage::helper('connector')->log(implode("\n", $errors), Zend_log::ERR);
173
+ return false;
174
+ }
175
+
176
+ return true;
177
+ }
178
+
179
+ /**
180
+ * Run update statues process. Download file for ready entities.
181
+ *
182
+ * @param mixed $force
183
+ * @return boolean
184
+ */
185
+ public function updateStatus($force = false) {
186
+
187
+ $attributesOptions = Mage::getSingleton('connector/content_attributes_options');
188
+ $contentCollection = $this->buildColection();
189
+
190
+ if(!$contentCollection) return false;
191
+
192
+ Mage::dispatchEvent('smartling_check_statuses_before',
193
+ array(
194
+ 'collection' => $contentCollection
195
+ ));
196
+
197
+ if($this->isLocked()) {
198
+ Mage::getSingleton('adminhtml/session')->addError(
199
+ Mage::helper('connector')->__('Sorry, check status process is locked')
200
+ );
201
+ return false;
202
+ } else {
203
+ $this->lock();
204
+ }
205
+
206
+ foreach ($contentCollection as $item) {
207
+
208
+ $cmsContentModel = Mage::getSingleton($item->getModelClass());
209
+
210
+ Mage::register('content_translate_row_data', $item->getData());
211
+
212
+ try {
213
+
214
+ /** @var Smartling_Connector_Model_Translator */
215
+ $connector = Mage::getModel('connector/translator',
216
+ array(
217
+ 'apiKey' => $item['api_key'],
218
+ 'projectId' => $item['project_code'],
219
+ 'project_id' => $item['project_id']
220
+ )
221
+ );
222
+
223
+ // check status of translation
224
+ $statusResponse = $connector->checkStatus($item['filename'], $item['locale']);
225
+
226
+ // check of unexpected format
227
+ if (!Mage::helper('connector')->isJson($statusResponse)) {
228
+ Mage::throwException(
229
+ Mage::helper('connector')
230
+ ->__('Invalid response. Expected type is JSON. Received: ')
231
+ . $statusResponse
232
+ );
233
+ } else {
234
+ $statusResponseData = json_decode($statusResponse, true);
235
+ $responseData = array();
236
+
237
+ if(isset($statusResponseData['response'])) {
238
+ $responseData = $statusResponseData['response'];
239
+ }
240
+
241
+ if(isset($responseData['messages']) && $responseData['code'] != 'SUCCESS') {
242
+ Mage::throwException(implode('; ', $responseData['messages']));
243
+ }
244
+
245
+ $percent =
246
+ Mage::helper('connector')->calculatePercent(
247
+ @$responseData['data']['completedStringCount'],
248
+ @$responseData['data']['stringCount']
249
+ );
250
+
251
+ $item->setPercent($percent);
252
+ }
253
+
254
+ if($force === true || $percent == 100) {
255
+
256
+ $response = $connector->downloadTranslatedContent($item['filename'],
257
+ $item['locale'],
258
+ array('retrievalType' => $item['retrieval_type'])
259
+ );
260
+
261
+ $translatedContent = $cmsContentModel->getTranslatedContent($response);
262
+
263
+ $newContent = $cmsContentModel
264
+ ->createContent(
265
+ $translatedContent,
266
+ $item['origin_content_id'],
267
+ $item['store_id']
268
+ );
269
+
270
+ Mage::dispatchEvent('smartling_apply_content_after',
271
+ array(
272
+ 'new_content' => $newContent,
273
+ 'cms_content_model_instanse' => $cmsContentModel,
274
+ 'item' => $item,
275
+ 'response' => $response,
276
+ ));
277
+ }
278
+
279
+ } catch (Mage_Core_Exception $e) {
280
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
281
+ Mage::getSingleton('adminhtml/session')->addError(
282
+ Mage::helper('connector')->__($e->getMessage())
283
+ );
284
+ } catch (Exception $e) {
285
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
286
+ Mage::getSingleton('adminhtml/session')->addError(
287
+ Mage::helper('connector')->__($e->getMessage())
288
+ );
289
+ }
290
+
291
+ Mage::unregister('content_translate_row_data');
292
+ }
293
+
294
+ Mage::dispatchEvent('smartling_check_statuses_after',
295
+ array(
296
+ 'attributes_options_instanse' => $attributesOptions,
297
+ 'items_collection' => $contentCollection
298
+ ));
299
+
300
+ return true;
301
+ }
302
+
303
+ /**
304
+ * Build and filter collection of none translated entities
305
+ * @return false|\Smartling_Connector_Model_Resource_Content_Collection
306
+ */
307
+ protected function buildColection()
308
+ {
309
+ $content_id = $this->getContentId();
310
+ $origin_content_id = $this->getOriginContentId();
311
+ $project_id = $this->getProjectId();
312
+ $storeId = $this->getStoreId();
313
+
314
+ try {
315
+ $contentCollection = Mage::getModel('connector/content')->getCollection();
316
+ $contentCollection->addFieldToFilter('filename', array('neq' => ''))
317
+ ->addFieldToFilter('percent', array('lt' => '100'));
318
+
319
+ if($content_id) { // identity field
320
+ $contentCollection->addIndentifyToFilter($content_id);
321
+ } elseif($origin_content_id && $project_id && $storeId) {
322
+ $contentCollection->addUniqueByParams($origin_content_id, $project_id, $storeId);
323
+ } else { // get all none updated records
324
+ $contentCollection->setPageSize(500)
325
+ ->setCurPage(1);
326
+ }
327
+
328
+ $contentCollection->joinAdditionalDetails();
329
+
330
+ return $contentCollection;
331
+ } catch (Exception $ex) {
332
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
333
+ return false;
334
+ }
335
+
336
+
337
+ }
338
+
339
+ /**
340
+ * Get lock file resource
341
+ *
342
+ * @return resource
343
+ */
344
+ protected function _getLockFile()
345
+ {
346
+ if ($this->_lockFile === null) {
347
+ $file = $this->getLockFilePath();
348
+ if (is_file($file)) {
349
+ $this->_lockFile = fopen($file, 'w');
350
+ } else {
351
+ $this->_lockFile = fopen($file, 'x');
352
+ }
353
+ fwrite($this->_lockFile, date('r'));
354
+ }
355
+ return $this->_lockFile;
356
+ }
357
+
358
+ protected function getLockFilePath() {
359
+ $varDir = Mage::getConfig()->getVarDir('locks');
360
+ $file = $varDir . DS . $this->_lockFileName;
361
+ return $file;
362
+ }
363
+
364
+ /**
365
+ * Lock process without blocking.
366
+ * This method allow protect multiple process runing and fast lock validation.
367
+ *
368
+ * @return Smartling_Connector_Model_Service
369
+ */
370
+ public function lock()
371
+ {
372
+ $this->_isLocked = true;
373
+ flock($this->_getLockFile(), LOCK_EX | LOCK_NB);
374
+ return $this;
375
+ }
376
+
377
+ /**
378
+ * Lock and block process.
379
+ * If new instance of the process will try validate locking state
380
+ * script will wait until process will be unlocked
381
+ *
382
+ * @return Smartling_Connector_Model_Service
383
+ */
384
+ public function lockAndBlock()
385
+ {
386
+ $this->_isLocked = true;
387
+ flock($this->_getLockFile(), LOCK_EX);
388
+ return $this;
389
+ }
390
+
391
+ /**
392
+ * Unlock process
393
+ *
394
+ * @return Smartling_Connector_Model_Service
395
+ */
396
+ public function unlock()
397
+ {
398
+ try {
399
+ if($this->isLocked()) {
400
+ $this->_isLocked = false;
401
+ @flock($this->_getLockFile(), LOCK_UN);
402
+ @unlink($this->getLockFilePath());
403
+ }
404
+ } catch (Mage_Exception $e) {
405
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
406
+ Mage::throwException($e->getMessage());
407
+ }
408
+ return $this;
409
+ }
410
+
411
+ /**
412
+ * Check if process is locked
413
+ *
414
+ * @return bool
415
+ */
416
+ public function isLocked()
417
+ {
418
+ if ($this->_isLocked !== null) {
419
+ return $this->_isLocked;
420
+ } else {
421
+ $fp = $this->_getLockFile();
422
+ if (flock($fp, LOCK_EX | LOCK_NB)) {
423
+ flock($fp, LOCK_UN);
424
+ return false;
425
+ }
426
+ return true;
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Close file resource if it was opened
432
+ */
433
+ public function __destruct()
434
+ {
435
+ if ($this->isLocked()) {
436
+ $this->unlock();
437
+ }
438
+ }
439
+
440
+ }
app/code/community/Smartling/Connector/Model/Service/Observer.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CallUpload
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Service_Observer
9
+ {
10
+ public function prepareAttributesOptions(Varien_Event_Observer $object) {
11
+
12
+ $data = $object->getEvent()->getData();
13
+
14
+ $cmsContentModel = $data['cms_content_model_instanse'];
15
+ $item = $data['item'];
16
+ $response = $data['response'];
17
+
18
+ if($cmsContentModel instanceof Smartling_Connector_Model_Content_EavEntityInterface) {
19
+ $translatedContent = $cmsContentModel->getTranslatedAttributesOptions($response);
20
+ $attributesOptions = Mage::getSingleton('connector/content_attributes_options');
21
+
22
+ foreach ($translatedContent as $optionValue) {
23
+ $attributesBiulder = Mage::getModel('connector/content_attributes_builder');
24
+
25
+ $attributesBiulder->setStoreId($item['store_id'])
26
+ ->setOptionId($optionValue['option_id'])
27
+ ->setValue($optionValue['value']);
28
+
29
+ $params = $attributesBiulder->buildParameters();
30
+ $attributesOptions->add($params);
31
+ }
32
+ }
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @param Varien_Event_Observer $object
38
+ */
39
+ public function updateTranslatedContentId(Varien_Event_Observer $object) {
40
+
41
+ $data = $object->getEvent()->getData();
42
+ $item = $data['item'];
43
+ $newContent = $data['new_content'];
44
+
45
+ if (is_object($newContent) && $newContent->getId()) {
46
+
47
+ if (is_null($item->getTranslatedContentId($newContent->getId()))) {
48
+ $item->setTranslatedContentId($newContent->getId());
49
+ }
50
+
51
+ try {
52
+
53
+ $logMessage = sprintf('Smartling saves the original xml file for entity type = %s, id = %s. Locale: %s. Project: %s',
54
+ $item->getModelClass(),
55
+ $newContent->getId(),
56
+ $item['locale'],
57
+ $item['project_code']
58
+ );
59
+
60
+ $item->save();
61
+ Mage::helper('connector')->log($logMessage, Zend_log::DEBUG);
62
+ } catch (Mage_Exception $e) {
63
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
64
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Import attributes options
71
+ * @param Varien_Event_Observer $object
72
+ */
73
+ public function importEavOptions(Varien_Event_Observer $object) {
74
+
75
+ $data = $object->getEvent()->getData();
76
+ $attributesOptions = $data['attributes_options_instanse'];
77
+
78
+ $attributesOptions->run();
79
+ }
80
+
81
+ /**
82
+ * Set compeleted status to translated entities
83
+ * @param Varien_Event_Observer $object
84
+ */
85
+ public function updateContentStatuses(Varien_Event_Observer $object) {
86
+
87
+ $contentModel = Mage::getModel('connector/content');
88
+ $contentCollection = $contentModel->getCollection();
89
+
90
+ $contentCollection->addFieldToFilter('percent', array('eq' => 100))
91
+ ->addFieldToFilter('status', array('neq' => $contentModel::CONTENT_STATUS_COMPLETED));
92
+
93
+ foreach ($contentCollection as $item) {
94
+ $item->setStatus($contentModel::CONTENT_STATUS_COMPLETED);
95
+ $item->save();
96
+ }
97
+
98
+ }
99
+
100
+ }
app/code/community/Smartling/Connector/Model/SmartlingAPI.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translator
5
+ *
6
+ * @author Smartling
7
+ */
8
+ require_once(Mage::getBaseDir('lib') . '/SmartlingApi/lib/SmartlingAPI.php');
9
+
10
+ class Smartling_Connector_Model_SmartlingAPI
11
+ extends SmartlingAPI
12
+ {
13
+ /**
14
+ * Flag for mock response data
15
+ * @var int
16
+ */
17
+ protected $_mock_data;
18
+
19
+ /**
20
+ * Flag for mock response data
21
+ * @var int
22
+ */
23
+ protected $_mock_response_file = 'unit_test_file.xml';
24
+
25
+ /**
26
+ * Flag for mock response data
27
+ * @var int
28
+ */
29
+ protected $_mock_files_dir = 'var/smartling/';
30
+
31
+ /**
32
+ * The chapter which will be added to translated content in "mock response" mode
33
+ * @var string
34
+ */
35
+ protected $_test_char = '~';
36
+
37
+ /**
38
+ *
39
+ * @var array
40
+ */
41
+ protected $_testText = array('Smartling test product', 'test text', 'Title');
42
+
43
+
44
+ public function __construct($options = array()) {
45
+
46
+ $this->_mock_files_dir = Mage::getBaseDir('var') . DS . 'smartling' . DS;
47
+
48
+ $this->_mock_data = Mage::getStoreConfig('dev/smartling/mock_data');
49
+
50
+ if($this->_mock_data == 1) {
51
+ if(!is_dir($this->_mock_files_dir)) {
52
+ try {
53
+ mkdir($this->_mock_files_dir, 0777, true);
54
+ } catch (Exception $ex) {
55
+ Mage::logException($ex);
56
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
57
+ }
58
+ }
59
+ }
60
+
61
+ parent::__construct(@$options[0], @$options[1], @$options[2], self::PRODUCTION_MODE);
62
+ }
63
+
64
+ /**
65
+ * upload content to Smartling service
66
+ *
67
+ * @param string $content
68
+ * @param string $fileType
69
+ * @param string $fileUri
70
+ * @param array $params
71
+ * @return string
72
+ */
73
+ public function uploadContent($content, $params = array()) {
74
+
75
+ $response = false;
76
+
77
+ if($this->_mock_data == 1) {
78
+
79
+ $filePath = $this->getTestFilePath();
80
+
81
+ try {
82
+
83
+ if (is_file($filePath) && !is_writable($filePath)) {
84
+ Mage::throwException("Can not write to file {$filePath}");
85
+ } elseif(!is_writable($this->_mock_files_dir)) {
86
+ Mage::throwException("Can not write to dir {$this->_mock_files_dir}");
87
+ }
88
+
89
+ $fp = fopen($filePath, 'w+');
90
+ fwrite($fp, $content);
91
+ fclose($fp);
92
+
93
+ $response = '{"response":{"data":{"wordCount":16,"stringCount":5,"overWritten":false},"code":"SUCCESS","messages":[]}}';
94
+
95
+ } catch (Mage_Core_Exception $ex) {
96
+ Mage::logException($ex);
97
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
98
+ }
99
+
100
+ } else {
101
+ $response = parent::uploadContent($content, $params);
102
+ }
103
+
104
+ Mage::helper('connector')->log($response, Zend_log::DEBUG);
105
+
106
+ return $response;
107
+ }
108
+
109
+ /**
110
+ * Download translated content from Smartling Service
111
+ *
112
+ * @param string $fileUri
113
+ * @param string $locale
114
+ * @return string|false
115
+ */
116
+ public function downloadFile($fileUri, $locale, $params = array()) {
117
+
118
+ $response = false;
119
+
120
+ if($this->_mock_data == 1) {
121
+
122
+ $filePath = $this->getTestFilePath();
123
+
124
+ try {
125
+ if(!file_exists($filePath)) {
126
+ Mage::throwException("Download file {$filePath} not exists");
127
+ }
128
+
129
+ $xmlContent = simplexml_load_file($filePath);
130
+
131
+ $nodesQueries = array(
132
+ '//data/translate/htmlcontent',
133
+ '//data/translate/content',
134
+ '//data/translate/select/item'
135
+ );
136
+ $nodes = $xmlContent->xpath( implode('|', $nodesQueries) );
137
+
138
+ foreach ($nodes as $node) {
139
+
140
+ $nodeValue = $node->__toString();
141
+ if(!$nodeValue) continue;
142
+
143
+ $node->{0} = $this->makeTestContent($nodeValue);
144
+ }
145
+
146
+ $response = $xmlContent->asXML();
147
+
148
+ } catch (Mage_Core_Exception $ex) {
149
+ Mage::logException($ex);
150
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
151
+ }
152
+
153
+ } else {
154
+
155
+ Mage::helper('connector')->log('Download file request. '
156
+ . ' fileUri: ' . $fileUri . '; '
157
+ . ' Params: ' . serialize($params) . '; '
158
+ . ' Locale: ' . $locale . '; '
159
+ . ' projectId: sendRequest' . $this->_projectId
160
+ . ' Credential: apiKey: ' . $this->protectPasw($this->_apiKey) . ';'
161
+ . ' baseUrl: ' . $this->_baseUrl
162
+ ,Zend_log::DEBUG);
163
+
164
+ $response = parent::downloadFile($fileUri, $locale, $params);
165
+ }
166
+
167
+ Mage::helper('connector')->log('Download file response. ' . $response, Zend_log::DEBUG);
168
+
169
+ return $response;
170
+ }
171
+
172
+ /**
173
+ *
174
+ * @param string $string
175
+ * @return string
176
+ */
177
+ public function makeTestContent($string) {
178
+
179
+ $string_len = strlen($string);
180
+
181
+ for($i = 1; $i < round($string_len / 2); $i++) {
182
+ $position = rand(1,$string_len);
183
+ $string = substr($string,0,$position) . $this->_test_char . substr($string,$position);
184
+ }
185
+
186
+ return $string;
187
+ }
188
+
189
+ public function getTestFilePath() {
190
+ return $this->_mock_files_dir . $this->_mock_response_file;
191
+ }
192
+
193
+ /**
194
+ * retrieve status about file translation progress
195
+ *
196
+ * @param string $fileUri
197
+ * @param string $locale
198
+ * @return string
199
+ */
200
+ public function getStatus($fileUri, $locale, $params = array()) {
201
+
202
+ $sendData = array_replace_recursive(array(
203
+ 'fileUri' => $fileUri,
204
+ 'locale' => $locale
205
+ ), $params);
206
+
207
+ $uri = 'file/status';
208
+
209
+ if($this->_mock_data == 1) {
210
+ return '{"response":{"data":{"fileUri":"' . $fileUri . '","wordCount":108,"fileType":"xml","callbackUrl":"","lastUploaded":"2014-12-16T00:23:33","stringCount":2,"approvedStringCount":2,"completedStringCount":0},"code":"SUCCESS","messages":[]}}';
211
+ }
212
+
213
+ Mage::helper('connector')->log('getStatus request: ' . serialize($sendData) . '; '
214
+ . ' projectId: sendRequest' . $this->_projectId
215
+ . ' Credential: apiKey: ' . $this->protectPasw($this->_apiKey) . ';'
216
+ . ' API Url: ' . $this->_baseUrl . "/" . $uri
217
+ ,Zend_log::DEBUG);
218
+
219
+
220
+ $response = $this->sendRequest($uri, $sendData, HttpClient::REQUEST_TYPE_GET);
221
+
222
+ Mage::helper('connector')->log('getStatus response. ' . $response, Zend_log::DEBUG);
223
+
224
+ return $response;
225
+ }
226
+
227
+ private function protectPasw($string) {
228
+ $length = strlen($string);
229
+
230
+ $visibleChaptersLength = round($length * 0.2);
231
+ $preplaceSrtinglength = $length - ($visibleChaptersLength*2);
232
+
233
+ $string = substr($string, 0, $visibleChaptersLength)
234
+ . str_repeat('X', $preplaceSrtinglength)
235
+ . substr($string, -$visibleChaptersLength);
236
+
237
+ return $string;
238
+ }
239
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Attributes/Category.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Category
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Attributes_Category
9
+ {
10
+
11
+ /**
12
+ * get category attributes collection
13
+ *
14
+ * @return array
15
+ */
16
+ public function toOptionArray(){
17
+ $options = array();
18
+ $attributes = $this->_getAttributesCollection();
19
+
20
+ foreach ($attributes as $_attribute){
21
+ $options[] = array(
22
+ 'label' => $_attribute->getFrontendLabel(),
23
+ 'value' => $_attribute->getId(),
24
+ );
25
+ }
26
+ return $options;
27
+ }
28
+
29
+ /**
30
+ * Returns category attributes collection
31
+ *
32
+ * @return \Mage_Eav_Resource_Entity_Attribute_Collection
33
+ */
34
+ protected function _getAttributesCollection(){
35
+ $allowedFields = array('text', 'textarea');
36
+ $entityType = Mage::getModel('connector/content_category')->getEntityTypeId();
37
+ $attributesCollection = Mage::getResourceModel('eav/entity_attribute_collection')
38
+ ->setEntityTypeFilter($entityType)
39
+ ->addFieldToFilter('frontend_input', array('in' => $allowedFields));
40
+ return $attributesCollection;
41
+ }
42
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Attributes/Product.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Product
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Attributes_Product
9
+ {
10
+
11
+ /**
12
+ * List of product attributes
13
+ *
14
+ * @return array
15
+ */
16
+ public function toOptionArray(){
17
+ $options = array();
18
+ $attributes = $this->_getAttributesCollection();
19
+
20
+ foreach ($attributes as $_attribute){
21
+ $options[] = array(
22
+ 'label' => $_attribute->getFrontendLabel(),
23
+ 'value' => $_attribute->getId(),
24
+ );
25
+ }
26
+ return $options;
27
+ }
28
+
29
+ /**
30
+ * Returns product attributes collection
31
+ *
32
+ * @return Mage_Catalog_Resource_Product_Attribute_Collection
33
+ */
34
+ protected function _getAttributesCollection(){
35
+ $allowedFields = array('text', 'textarea');
36
+ $collection = Mage::getResourceModel('catalog/product_attribute_collection')
37
+ ->addFieldToFilter('frontend_label', array('neq' => ''))
38
+ ->addFieldToFilter('frontend_input', array('in' => $allowedFields));
39
+ return $collection;
40
+ }
41
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Fields/CmsBlock.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsBlock
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Fields_CmsBlock
9
+ {
10
+
11
+ /**
12
+ * Returns list of all fields in cms/page table
13
+ *
14
+ * @return array
15
+ */
16
+ public function toOptionArray(){
17
+ $options = array();
18
+ $table = 'cms_block';
19
+ $fields = Mage::helper('connector')->getFields($table);
20
+
21
+ for ($i = 0; $i < sizeof($fields); $i++){
22
+ $options[] = array(
23
+ 'label' => $fields[$i],
24
+ 'value' => $fields[$i]
25
+ );
26
+ }
27
+ return $options;
28
+ }
29
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Fields/CmsPage.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsPage
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Fields_CmsPage
9
+ {
10
+
11
+ /**
12
+ * Returns list of all fields in cms/page table
13
+ *
14
+ * @return array
15
+ */
16
+ public function toOptionArray(){
17
+ $options = array();
18
+ $table = 'cms_page';
19
+ $fields = Mage::helper('connector')->getFields($table);
20
+
21
+ for ($i = 0; $i < sizeof($fields); $i++){
22
+ $options[] = array(
23
+ 'label' => $fields[$i],
24
+ 'value' => $fields[$i]
25
+ );
26
+ }
27
+ return $options;
28
+ }
29
+
30
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Status.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Status
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Status
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @return array
14
+ */
15
+ public function getOptions(){
16
+ return array(
17
+ Smartling_Connector_Model_Content::CONTENT_STATUS_PROCESS => 'In Progress',
18
+ Smartling_Connector_Model_Content::CONTENT_STATUS_COMPLETED => 'Completed',
19
+ );
20
+ }
21
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Stores.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Stores
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Stores
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @return array
14
+ */
15
+ public function toOptionArray() {
16
+ $stores = Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, false);
17
+ $defaultStore = Mage::helper('connector')->getSourceStoreView();
18
+
19
+ if (sizeof($stores) == 0) {
20
+ return array();
21
+ }
22
+
23
+ $translateStores = array();
24
+
25
+ foreach ($stores as &$store) {
26
+ if (is_array($store['value'])) {
27
+ for ($i = 0; $i < sizeof($store['value']); $i++) {
28
+ if ($store['value'][$i]['value'] == $defaultStore) {
29
+ unset ($store['value'][$i]);
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ return $stores;
36
+ }
37
+ }
app/code/community/Smartling/Connector/Model/Source/Content/Types.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Content_Types
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @return array
14
+ */
15
+ public function getOptions(){
16
+ $typesCollection = $this->_getTypesCollection();
17
+ $options = array();
18
+ if ($typesCollection->getSize()){
19
+ foreach ($typesCollection as $_type){
20
+ $options[$_type->getTypeId()] = $_type->getTypeName();
21
+ }
22
+ }
23
+ return $options;
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @return array
29
+ */
30
+ public function getList(){
31
+ $typesCollection = $this->_getTypesCollection();
32
+ $options = array();
33
+ if ($typesCollection->getSize()){
34
+ foreach ($typesCollection as $_type){
35
+ $options[$_type->getTypeId()] = $_type->getData();
36
+ }
37
+ }
38
+ return $options;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @return array
44
+ */
45
+ public function toOptionArray(){
46
+ $typesCollection = $this->_getTypesCollection();
47
+ $options = array();
48
+ if ($typesCollection->getSize() > 0){
49
+ foreach ($typesCollection as $_type){
50
+ $options[] = array(
51
+ 'value' => $_type->getTypeId(),
52
+ 'label' => $_type->getTitle(),
53
+ );
54
+ }
55
+ }
56
+ return $options;
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @return \Smartling_Connector_Model_Resource_Types_Collection
62
+ */
63
+ protected function _getTypesCollection(){
64
+ return Mage::getModel('connector/content_types')->getCollection();
65
+ }
66
+
67
+ }
app/code/community/Smartling/Connector/Model/Source/Log/Level.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Log_Level
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @return array
14
+ */
15
+ public function toOptionArray() {
16
+
17
+ $levels = Mage::helper('connector')->getLogLevels();
18
+ $options = array();
19
+
20
+ foreach ($levels as $value => $label) {
21
+ $options[] = array(
22
+ 'value' => $value,
23
+ 'label' => $label,
24
+ );
25
+ }
26
+
27
+ return $options;
28
+ }
29
+ }
app/code/community/Smartling/Connector/Model/Source/Projects.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Website
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Projects
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @var int
14
+ */
15
+ protected $_website_id;
16
+
17
+ /**
18
+ *
19
+ * @param array $data
20
+ */
21
+ public function setData($data) {
22
+ $this->_projectsLocales = $data;
23
+
24
+ return $this;
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @return array
30
+ */
31
+ public function toOptionArray(){
32
+
33
+ if(!is_array($this->_projectsLocales) || !sizeof($this->_projectsLocales)) {
34
+ return array();
35
+ }
36
+
37
+ $list = array();
38
+
39
+ foreach ($this->_projectsLocales as $locale) {
40
+
41
+ if($this->_website_id
42
+ && $locale['website_id'] != $this->_website_id
43
+ || !sizeof($locale['locales'])) {
44
+ continue;
45
+ }
46
+
47
+ $listValues = array();
48
+ foreach ($locale['locales'] as $localeValues) {
49
+ $listValues[] = array(
50
+ 'label' => $localeValues['name'],
51
+ 'value' => $localeValues['project_identity']
52
+ );
53
+ }
54
+
55
+ $list[] = array(
56
+ 'label' => $locale['name'],
57
+ 'value' => $listValues
58
+ );
59
+ }
60
+
61
+ return $list;
62
+ }
63
+
64
+ /**
65
+ * Set website ID to filter list
66
+ * @param int $website_id
67
+ */
68
+ public function addWebsiteIdToFilter($website_id) {
69
+ $this->_website_id = $website_id;
70
+ return $this;
71
+ }
72
+ }
app/code/community/Smartling/Connector/Model/Source/Stores.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Website
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Stores
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @param bool $includeDefault - Use "0" as first item
14
+ * @return array
15
+ */
16
+ public function toOptionArray($includeDefault = false){
17
+
18
+ $list = array();
19
+
20
+ if($includeDefault) {
21
+ $list[] = array(
22
+ 'value' => 0,
23
+ 'label' => Mage::helper('connector')->__('Please select store to see available profiles')
24
+ );
25
+ }
26
+
27
+ $resource = Mage::getSingleton('core/resource');
28
+
29
+ $stores = Mage::getResourceModel('core/store_group_collection');
30
+ $stores->getSelect()
31
+ ->reset(Zend_Db_Select::COLUMNS)
32
+ ->columns(array('group_id', 'name'))
33
+ ->joinInner(array('s' => $resource->getTableName('core_store')),
34
+ 'main_table.group_id = s.group_id',
35
+ array())
36
+ ->joinInner(array('pl' => $resource->getTableName('connector/projects_locales')),
37
+ 's.store_id = pl.store_id',
38
+ array())
39
+ ->group('group_id');
40
+
41
+ foreach ($stores as $store) {
42
+
43
+ $list[] = array(
44
+ 'value' => $store->getGroupId(),
45
+ 'label' => $store->getName()
46
+ );
47
+ }
48
+
49
+ return $list;
50
+ }
51
+ }
app/code/community/Smartling/Connector/Model/Source/Types.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Types
5
+ *
6
+ * @author Itdelight
7
+ */
8
+ class Smartling_Connector_Model_Source_Types
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @return array
14
+ */
15
+ public function toOptionArray(){
16
+ return array(
17
+ array(
18
+ 'value' => Smartling_Connector_Model_Translator::FILE_TYPE_JSON,
19
+ 'label' => 'JSON',
20
+ ),
21
+ array(
22
+ 'value' => Smartling_Connector_Model_Translator::FILE_TYPE_XML,
23
+ 'label' => 'XML',
24
+ ),
25
+ );
26
+ }
27
+ }
app/code/community/Smartling/Connector/Model/Source/Websites.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Website
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Source_Websites
9
+ {
10
+ /**
11
+ *
12
+ * @param bool $includeDefault - Use "0" as first item
13
+ * @return array
14
+ */
15
+ public function toOptionArray($includeDefault = false){
16
+
17
+ $websites = Mage::app()->getWebsites();
18
+ $list = array();
19
+
20
+ if($includeDefault) {
21
+ $list[] = array(
22
+ 'value' => 0,
23
+ 'label' => Mage::helper('connector')->__('Please select website to see available profiles')
24
+ );
25
+ }
26
+
27
+ foreach ($websites as $website) {
28
+ $list[] = array(
29
+ 'value' => $website->getWebsiteId(),
30
+ 'label' => $website->getName(),
31
+ );
32
+ }
33
+
34
+ return $list;
35
+ }
36
+ }
app/code/community/Smartling/Connector/Model/Translate/Attributes.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Translate_Attributes
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ * set resource model
14
+ *
15
+ */
16
+ protected function _construct() {
17
+ $this->_init('connector/translate_attributes');
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @param int $columnValue
23
+ * @param string $columnName
24
+ * @param int $entity_type_id
25
+ * @return type
26
+ */
27
+ public function load($columnValue, $columnName = 'id', $entity_type_id = 4) {
28
+
29
+ $collection = $this->getCollection()
30
+ ->addFieldToFilter($columnName, $columnValue)
31
+ ->addFieldToFilter('entity_type_id', $entity_type_id);
32
+
33
+ return $collection->getFirstItem();
34
+ }
35
+ }
app/code/community/Smartling/Connector/Model/Translate/Fields.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Content
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Translate_Fields
9
+ extends Mage_Core_Model_Abstract
10
+ {
11
+
12
+ /**
13
+ * set resource model
14
+ *
15
+ */
16
+ protected function _construct() {
17
+ $this->_init('connector/translate_fields');
18
+ }
19
+ }
app/code/community/Smartling/Connector/Model/Translate/StatusInterface.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Interface
5
+ *
6
+ * @author Smartling
7
+ */
8
+ interface Smartling_Connector_Model_Translate_StatusInterface
9
+ {
10
+ /**
11
+ * @return Zend_Controller_Response_Abstract
12
+ */
13
+ public function changeStatusAction();
14
+
15
+ }
app/code/community/Smartling/Connector/Model/Translator.php ADDED
@@ -0,0 +1,597 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translator
5
+ *
6
+ * @author snail
7
+ */
8
+
9
+
10
+ class Smartling_Connector_Model_Translator
11
+ extends Mage_Core_Model_Abstract
12
+ {
13
+
14
+ /**
15
+ * xml file type for Smartling Api while uploading files
16
+ */
17
+ const FILE_TYPE_XML = "xml";
18
+
19
+ /**
20
+ * CSV file type for Smartling Api while uploading files
21
+ */
22
+ const FILE_TYPE_CSV = "csv";
23
+
24
+ /**
25
+ * test mode Smartling API
26
+ */
27
+ const TEST_MODE = 'SANDBOX';
28
+
29
+ /**
30
+ * production mode Smartling API
31
+ */
32
+ const PRODUCTION_MODE = 'PRODUCTION';
33
+
34
+ /**
35
+ *
36
+ * @var null | SmartlingAPI
37
+ */
38
+ protected $_smartlingApiModel = null;
39
+
40
+ /**
41
+ *
42
+ * @var string
43
+ */
44
+ protected $_code = 'smartling';
45
+
46
+ /**
47
+ *
48
+ * @var string
49
+ */
50
+ protected $_apiKey = null;
51
+
52
+ /**
53
+ *
54
+ * @var string
55
+ */
56
+ protected $_projectId = null;
57
+
58
+
59
+ /**
60
+ * List of Smartling API lib objects
61
+ * @var array
62
+ */
63
+ protected $_smartlingObjectPool = null;
64
+
65
+ /**
66
+ * List of Smartling API data
67
+ * @var array
68
+ */
69
+ protected $_projectsDataPool = null;
70
+
71
+ /**
72
+ * @var string
73
+ */
74
+ protected $_objectPoolKeyPrefix = 'smartling_';
75
+
76
+
77
+ protected function _construct() {
78
+ $this->_init('connector/translator');
79
+ }
80
+
81
+ /**
82
+ * instantiate SmartlingApi object
83
+ *
84
+ * @params $options
85
+ */
86
+ public function __construct($options = array()) {
87
+
88
+ if (sizeof($options)) {
89
+ $this->setProjectData($options);
90
+ }
91
+
92
+ if($options['project_id']) {
93
+ $this->initSmartlingApiInstance($options['project_id']);
94
+ }
95
+
96
+ $this->_fileType = self::FILE_TYPE_XML;
97
+ }
98
+
99
+ protected function getProjectSettings($project_id) {
100
+ return $this->_projectsDataPool[$project_id];
101
+ }
102
+
103
+ /**
104
+ *
105
+ * @param array $options
106
+ */
107
+ protected function setProjectData(array $options) {
108
+ if(is_null($this->_projectsDataPool[$options['project_id']]) && $options['project_id']) {
109
+
110
+ if(isset($options['locales']) && !is_array($options['locales'])) {
111
+ $options['locales'] = explode(',', $options['locales']);
112
+ }
113
+
114
+ $this->_projectsDataPool[$options['project_id']] = $options;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Deprecated in newest version
120
+ *
121
+ * @param string $path
122
+ * @param string $fileUri
123
+ * @return string
124
+ */
125
+ public function uploadTranslateData($path, $fileUri, $params = array()){
126
+
127
+ $fileType = $this->_getFileType();
128
+ $project_id = $this->getCurrentProjectId();
129
+ $locales = $this->_projectsDataPool[$project_id]['locales'];
130
+
131
+ $upload_params = new FileUploadParameterBuilder();
132
+ $upload_params->setLocalesToApprove($locales)
133
+ ->setFileUri($fileUri)
134
+ ->setFileType($fileType)
135
+ ->setOverwriteApprovedLocales(0)
136
+ ->setApproved(0);
137
+
138
+ Mage::helper('connector')->log("Upload file " . $path, Zend_log::DEBUG);
139
+
140
+ $params = array_replace_recursive($upload_params->buildParameters(), $params);
141
+
142
+ $responce = $this->_smartlingApiModel
143
+ ->uploadFile($path, $params);
144
+
145
+ return $responce;
146
+ }
147
+
148
+ /**
149
+ * upload content for translation
150
+ *
151
+ * @param type $content
152
+ * @param type $fileUri
153
+ * @return string
154
+ */
155
+ public function uploadTranslateContent($content, $fileUri){
156
+
157
+ $fileType = $this->_getFileType();
158
+ $project_id = $this->getCurrentProjectId();
159
+ $locales = $this->_projectsDataPool[$project_id]['locales'];
160
+
161
+ $upload_params = new FileUploadParameterBuilder();
162
+ $upload_params->setLocalesToApprove($locales)
163
+ ->setFileUri($fileUri)
164
+ ->setFileType($fileType)
165
+ ->setOverwriteApprovedLocales(0)
166
+ ->setApproved(0);
167
+
168
+ Mage::helper('connector')->log($content, Zend_log::DEBUG);
169
+
170
+ $tmpfname = tempnam("/tmp", "smartling_");
171
+ $handle = fopen($tmpfname, "w");
172
+ fwrite($handle, $content);
173
+ fclose($handle);
174
+
175
+ $responce = $this->_smartlingApiModel
176
+ ->uploadFile($tmpfname, $upload_params->buildParameters());
177
+ unlink($tmpfname);
178
+
179
+
180
+ return $responce;
181
+ }
182
+
183
+ /**
184
+ *
185
+ * @param string $locale
186
+ * @return string
187
+ */
188
+ public function getTranslationsInfo($locale, $params = null){
189
+ return $this->_smartlingApiModel
190
+ ->getList($locale, $params);
191
+ }
192
+
193
+ /**
194
+ *
195
+ * @param string $fileUri
196
+ * @param string $locale
197
+ * @param array $params
198
+ * @return string
199
+ */
200
+ public function downloadTranslatedContent($fileUri, $locale, $params = array()){
201
+ return $this->_smartlingApiModel
202
+ ->downloadFile($fileUri, $locale, $params);
203
+ }
204
+
205
+ /**
206
+ *
207
+ * @param string $fileUri
208
+ * @param string $locale
209
+ * @param array $params
210
+ * @return string
211
+ */
212
+ public function checkStatus($fileUri, $locale){
213
+ return $this->_smartlingApiModel
214
+ ->getStatus($fileUri, $locale);
215
+ }
216
+
217
+ /**
218
+ *
219
+ * @param int $mage_project_id
220
+ * @return boolean|\SmartlingAPI
221
+ * @throws Varien_Exception
222
+ */
223
+ protected function initSmartlingApiInstance($mage_project_id) {
224
+
225
+ $this->setCurrentProjectId($mage_project_id);
226
+
227
+ if(!isset($this->_projectsDataPool[$mage_project_id])) {
228
+ $collection = Mage::getModel('connector/projects')->getProjectData($mage_project_id);
229
+ if($collection !== false) {
230
+ $this->_projectsDataPool[$mage_project_id]['apiKey'] = $collection->getKey();
231
+ $this->_projectsDataPool[$mage_project_id]['projectId'] = $collection->getProjectsId();
232
+ } else {
233
+ return false;
234
+ }
235
+ }
236
+
237
+
238
+ $smartlingObjectPoolKey = $this->getPoolObjectKey($mage_project_id);
239
+
240
+ $smartlingObject = Mage::objects($smartlingObjectPoolKey);
241
+
242
+ if($smartlingObject instanceof Smartling_Connector_Model_SmartlingAPI) {
243
+ $this->_smartlingApiModel = $smartlingObject;
244
+ return $smartlingObject;
245
+ } elseif( ($smartlingObject instanceof Smartling_Connector_Model_SmartlingAPI)===false && isset($smartlingObject)) {
246
+ throw new Varien_Exception('Smartling Object with key ' . $smartlingObjectPoolKey . ' has unexpected type.');
247
+ }
248
+
249
+ $smartlingObject = $this->getApi(null,
250
+ $this->_projectsDataPool[$mage_project_id]['apiKey'],
251
+ $this->_projectsDataPool[$mage_project_id]['projectId'],
252
+ $this->_mode()
253
+ );
254
+
255
+ Mage::objects()->save($smartlingObject, $smartlingObjectPoolKey);
256
+
257
+ $this->_smartlingApiModel = & $smartlingObject;
258
+
259
+ return $this->_smartlingApiModel;
260
+ }
261
+
262
+ /**
263
+ * Init object with API params for test connection
264
+ * @param array $options
265
+ * @return SmartlingAPI
266
+ */
267
+ protected function setSmartlingApiInstance($options) {
268
+
269
+ Mage::helper('connector')->log($options, Zend_log::DEBUG);
270
+ Mage::helper('connector')->log($this->_mode(), Zend_log::DEBUG);
271
+
272
+ $smartlingObject = $this->getApi(null,
273
+ $options['apiKey'],
274
+ $options['projectId'],
275
+ $this->_mode()
276
+ );
277
+
278
+ $this->_smartlingApiModel = & $smartlingObject;
279
+
280
+ return $this->_smartlingApiModel;
281
+ }
282
+
283
+ /**
284
+ *
285
+ * @param int $mage_project_id
286
+ * @return string
287
+ */
288
+ private function getPoolObjectKey($mage_project_id) {
289
+ return $this->_objectPoolKeyPrefix . $mage_project_id;
290
+ }
291
+
292
+ /**
293
+ * @param int $mage_project_id
294
+ * @return \SmartlingApi_lib_SmartlingAPI
295
+ */
296
+ public function getSmartlingApiInstance($mage_project_id) {
297
+
298
+ $smartlingObjectPoolKey = $this->getPoolObjectKey($mage_project_id);
299
+ $smartlingObject = Mage::objects($smartlingObjectPoolKey);
300
+
301
+ if (is_null($smartlingObject)) {
302
+ return $smartlingObject;
303
+ } else {
304
+ return $this->initSmartlingApiInstance($mage_project_id);
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Depricated. Use credentials from projects list instead.
310
+ *
311
+ * @return string
312
+ */
313
+ protected function _getApiKey(){
314
+ if (is_null($this->_apiKey)){
315
+
316
+ if ($apiKey = $this->_getConfigData('settings/api_key')){
317
+ $this->_apiKey = Mage::helper('core')->decrypt($apiKey);
318
+ } else {
319
+ $this->_apiKey = '';
320
+ }
321
+ }
322
+ return $this->_apiKey;
323
+ }
324
+
325
+ /**
326
+ * Depricated. Use credentials from projects list instead.
327
+ *
328
+ * @return string
329
+ */
330
+ protected function _getProjectId(){
331
+ if (is_null($this->_projectId)){
332
+
333
+ if ($projectId = $this->_getConfigData('settings/project_id')){
334
+ $this->_projectId = Mage::helper('core')->decrypt($projectId);
335
+ } else {
336
+ $this->_projectId = "";
337
+ }
338
+ }
339
+ return $this->_projectId;
340
+ }
341
+
342
+ /**
343
+ *
344
+ * @param string $path
345
+ * @return string
346
+ */
347
+ protected function _getConfigData($path){
348
+ return Mage::helper('connector')->getConfig($this->_code, $path);
349
+ }
350
+
351
+ /**
352
+ * @return bool
353
+ */
354
+ protected function _getMode(){
355
+ if (!is_null(Mage::getStoreConfig('dev/smartling/mode'))){
356
+ if (Mage::getStoreConfig('dev/smartling/mode') == false){
357
+ return false;
358
+ }
359
+ }
360
+ return true;
361
+ }
362
+
363
+ /**
364
+ * @return string
365
+ */
366
+ protected function _mode(){
367
+ if ($this->_getMode()){
368
+ return self::TEST_MODE;
369
+ } else {
370
+ return self::PRODUCTION_MODE;
371
+ }
372
+ }
373
+
374
+ /**
375
+ *
376
+ * @return string | null
377
+ */
378
+ protected function _getFileType(){
379
+ return $this->_fileType;
380
+ }
381
+
382
+ /**
383
+ *
384
+ * @return string | null
385
+ */
386
+ public function setFileType($type){
387
+ $this->_fileType = $type;
388
+ }
389
+
390
+ /**
391
+ * @return stdClass | bool
392
+ */
393
+ public function convertResponse($response){
394
+ if (Mage::helper('connector')->isJson($response)){
395
+ return json_decode($response);
396
+ }
397
+ return false;
398
+ }
399
+
400
+ /**
401
+ * creates new/update existing rows in submissions table in case when content
402
+ * upload successfully.
403
+ *
404
+ * @param array $locale
405
+ * @param array $data
406
+ */
407
+ public function createFilesInProcess($locale, $data){
408
+ $process = Mage::getModel('connector/content');
409
+ $stores = implode(",", Mage::helper('connector')->getStoresIdByLocale($locale));
410
+ $process->setData($data)
411
+ ->setLocale($locale)
412
+ ->setStoreId($stores)
413
+ ->setPercent(0.00)
414
+ ->setStatus(Smartling_Connector_Model_Content::CONTENT_STATUS_PROCESS);
415
+ if ($translatedId = $this->findIdentityContent($stores, $data['origin_content_id'])) {
416
+ $process->setTranslatedContentId($translatedId);
417
+ }
418
+ try{
419
+ $process->save();
420
+ } catch(Mage_Exception $e){
421
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
422
+ }
423
+ }
424
+
425
+ /**
426
+ *
427
+ * @param int $typeId
428
+ * @return string
429
+ */
430
+ public function getModelByContentType($typeId){
431
+ $contentType = Mage::getModel('connector/content_types')->load((int)$typeId);
432
+ if (!$contentType->getId()){
433
+ Mage::getSingleton('admin/session')->addError(
434
+ Mage::helper('connector')->__('This type is not exists')
435
+ );
436
+ return;
437
+ }
438
+ return $contentType->getModel();
439
+ }
440
+
441
+ /**
442
+ *
443
+ * @param string $fileUri
444
+ * @param string $locale
445
+ * @return string (json)
446
+ */
447
+ public function updateContentStatus($fileUri, $locale){
448
+ return $this->_smartlingApiModel->getStatus($fileUri, $locale);
449
+ }
450
+
451
+ /**
452
+ * defines percent
453
+ *
454
+ * @param int $approved
455
+ * @param int $completed
456
+ */
457
+ public function translatedPart($approved, $completed){
458
+ if ($approved !== 0){
459
+ $result = ($completed/$approved)*100;
460
+ } else {
461
+ $result = 0.00;
462
+ }
463
+ return number_format($result, 2, '.', '');
464
+ }
465
+
466
+ /**
467
+ * find existing row in submission table with the stores and origin content id
468
+ * for updating it in future for cases when user download the same content
469
+ *
470
+ * @param type $stores
471
+ * @param type $originContent
472
+ */
473
+ public function findIdentityContent($stores, $originContent){
474
+ $contentCollection = Mage::getModel('connector/content')->getCollection()
475
+ ->addFieldToSelect('translated_content_id')
476
+ ->addFieldToFilter('store_id', array('eq' => $stores))
477
+ ->addFieldToFilter('origin_content_id', array('eq' => $originContent));
478
+ if ($contentCollection < 1){
479
+ return false;
480
+ }
481
+ $contentId = $contentCollection->getFirstItem()->getData('translated_content_id');
482
+ return $contentId;
483
+ }
484
+
485
+ /**
486
+ * upload new content to Smartling for translation. Check result. In case of
487
+ * successfull result save info about uploaded content to submission table.
488
+ * In case of errors save errors messages to session and show in further
489
+ *
490
+ * @param Smartling_Connector_Model_Content $contentModel
491
+ * @param Vairen_Object $contentObject
492
+ * @param array $processData
493
+ * @param string $file
494
+ */
495
+ public function uploadContent($contentModel, $locales, $processData, $content){
496
+ $entry = $this->_findContent($processData, $locales);
497
+ if (!empty($entry)) {
498
+ $fileUri = $entry['filename'];
499
+ $processData['content_id'] = $entry['content_id'];
500
+ } else {
501
+ $fileUri = $contentModel->getFileUri();
502
+ }
503
+ $response = $this->uploadTranslateContent($content, $fileUri);
504
+
505
+ Mage::helper('connector')->log($response, Zend_log::INFO);
506
+
507
+ if ($response && $this->convertResponse($response)){
508
+ $result = $this->convertResponse($response);
509
+ if ($result->response->code == 'SUCCESS') {
510
+ Mage::getSingleton('adminhtml/session')
511
+ ->addSuccess(
512
+ Mage::helper('connector')->__("Content has been successfully sent to Smartling")
513
+ );
514
+
515
+ //add uploaded content data to database
516
+ $processData['filename'] = $fileUri;
517
+ $this->createFilesInProcess($locales, $processData);
518
+
519
+
520
+ $message = Mage::helper('connector')->__('New file "%s" from "%s" for locales %s has been created',
521
+ $fileUri,
522
+ $processData['content_title'],
523
+ implode(",", $locales)
524
+ );
525
+ Mage::helper('connector')->log($message, Zend_log::INFO);
526
+
527
+ } else {
528
+ if (is_array($result->response->messages)){
529
+ $error = implode("; ", $result->response->messages);
530
+ } else {
531
+ $error = $result->response->messages;
532
+ }
533
+ Mage::getSingleton('adminhtml/session')
534
+ ->addError(Mage::helper('connector')->__($error));
535
+ }
536
+ } else {
537
+ Mage::getSingleton('adminhtml/session')
538
+ ->addError(Mage::helper('connector')->__("Incorrect response data"));
539
+ }
540
+ }
541
+
542
+ /**
543
+ *
544
+ * @param string $key
545
+ * @return \Smartling_Connector_Model_Translator
546
+ */
547
+ public function setApiKey($key){
548
+ $this->_apiKey = $key;
549
+ return $this;
550
+ }
551
+
552
+ /**
553
+ *
554
+ * @param string $projectId
555
+ * @return \Smartling_Connector_Model_Translator
556
+ */
557
+ public function setProjectId($projectId){
558
+ $this->_projectId = $projectId;
559
+ return $this;
560
+ }
561
+
562
+ /**
563
+ *
564
+ * @param string $response
565
+ * @return boolean
566
+ */
567
+ public function isSuccessResponse($response) {
568
+ if ($response == '' || is_null($response)){
569
+ return false;
570
+ }
571
+
572
+ $result = $this->convertResponse($response);
573
+
574
+ if ($result->response->code == 'SUCCESS') {
575
+ return true;
576
+ }
577
+
578
+ return false;
579
+ }
580
+
581
+ /**
582
+ *
583
+ * @param array $name
584
+ * @param string $locales
585
+ */
586
+ protected function _findContent($data, $locales) {
587
+ $resource = Mage::getResourceModel('connector/content');
588
+ return $resource->findContent($data, $locales);
589
+ }
590
+
591
+ public function getApi() {
592
+
593
+ $args = func_get_args();
594
+
595
+ return Mage::getModel('connector/SmartlingAPI', $args);
596
+ }
597
+ }
app/code/community/Smartling/Connector/Model/Translator/Observer.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CallUpload
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Translator_Observer
9
+ {
10
+ /**
11
+ * Set compeleted status to translated entities
12
+ * @param Varien_Event_Observer $object
13
+ */
14
+ public function fillSourceLocale(Varien_Event_Observer $object) {
15
+
16
+ try {
17
+
18
+ $resource = Mage::getSingleton('core/resource');
19
+ $_adapter = $resource->getConnection('write');
20
+
21
+ $contentTableName = $resource->getTableName('connector/translate_content');
22
+ $storeViewTableName = $resource->getTableName('core_store');
23
+ $storeGroupTableName = $resource->getTableName('core_store_group');
24
+
25
+ $updateQuery = "UPDATE {$contentTableName} sc "
26
+ . " inner join {$storeViewTableName} cs on sc.store_id = cs.store_id and sc.source_store_id is NULL "
27
+ . " inner join {$storeGroupTableName} csg on cs.group_id = csg.group_id "
28
+ . " SET sc.source_store_id = csg.default_store_id";
29
+
30
+ $_adapter->query($updateQuery);
31
+
32
+ } catch (Exception $ex) {
33
+ Mage::helper('connector')->log("Fill source locale observer. " . $ex->getMessage(), Zend_log::ERR);
34
+ return false;
35
+ }
36
+
37
+ return true;
38
+
39
+ }
40
+
41
+ /**
42
+ * Set names to content items
43
+ * @param Varien_Event_Observer $object
44
+ */
45
+ public function fillTitles(Varien_Event_Observer $object) {
46
+ $contentModel = $object->getEvent()->getData('model_instance');
47
+ if($contentModel instanceof Smartling_Connector_Model_Content_Interface) {
48
+ $contentModel->saveNames();
49
+ }
50
+ }
51
+ }
app/code/community/Smartling/Connector/Model/Types/Abstract.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Simple content node
5
+ *
6
+ * @author Smartling
7
+ */
8
+ abstract class Smartling_Connector_Model_Types_Abstract
9
+ {
10
+ /**
11
+ *
12
+ * @var \Smartling_Connector_Model_Types_General
13
+ */
14
+ protected $_contentInstance;
15
+
16
+ /**
17
+ *
18
+ * @param array $params
19
+ */
20
+ public function __construct($params = array()) {
21
+ $this->_contentInstance = $params['contentInstance'];
22
+ }
23
+
24
+ /**
25
+ *
26
+ * @param string $value
27
+ * @param array $attributes
28
+ */
29
+ abstract public function setContent($value, $attributes);
30
+
31
+ /**
32
+ *
33
+ * @return \Smartling_Connector_Model_Types_General
34
+ */
35
+ public function getInstance() {
36
+ return $this->_contentInstance;
37
+ }
38
+ }
app/code/community/Smartling/Connector/Model/Types/Content.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Simple content node
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Types_Content extends Smartling_Connector_Model_Types_Abstract
9
+ {
10
+ /**
11
+ *
12
+ * @param string $value
13
+ * @param array $attributes
14
+ */
15
+ public function setContent($value, $attributes) {
16
+
17
+ $this->_contentInstance->setTranslateContent(
18
+ $value,
19
+ array(
20
+ 'attribute' => $attributes['attribute'],
21
+ 'type' => $attributes['type']
22
+ ));
23
+
24
+ }
25
+ }
app/code/community/Smartling/Connector/Model/Types/General.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of General
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Types_General extends Smartling_Connector_Model_Types_Xml
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @param string $value
14
+ * @param array $attributes
15
+ * @param string $type
16
+ */
17
+ public function setContent($value, $attributes, $type = 'content') {
18
+
19
+ Mage::getModel('connector/types_' . $type, array('contentInstance' => $this))
20
+ ->setContent($value, $attributes);
21
+
22
+ }
23
+ }
app/code/community/Smartling/Connector/Model/Types/Htmlcontent.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Html content node
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Types_Htmlcontent extends Smartling_Connector_Model_Types_Abstract
9
+ {
10
+ /**
11
+ *
12
+ * @param string $value
13
+ * @param array $attributes
14
+ */
15
+ public function setContent($value, $attributes) {
16
+
17
+ $this->_contentInstance->setHtmlContent(
18
+ 'htmlcontent',
19
+ $value,
20
+ array(
21
+ 'attribute' => $attributes['attribute'],
22
+ 'type' => $attributes['type']
23
+ ));
24
+ }
25
+ }
app/code/community/Smartling/Connector/Model/Types/List.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * List content node
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Types_List extends Smartling_Connector_Model_Types_Abstract
9
+ {
10
+ /**
11
+ *
12
+ * @param array $value
13
+ * @param array $attributes
14
+ * @return false|void
15
+ */
16
+ public function setContent($values, $attributes) {
17
+
18
+ if(!sizeof($values)) return false;
19
+
20
+ $nodeName = 'select';
21
+ $this->_contentInstance->pushHtmlContentNodeName('select/item');
22
+
23
+ $contentNode = $this->_contentInstance->getXmlInstance()->createElement($nodeName);
24
+
25
+ if (!empty($attributes)) {
26
+ foreach ($attributes as $name => $value) {
27
+ $contentNode->setAttribute($name, $value);
28
+ }
29
+ }
30
+
31
+ // Set attibute values list
32
+ foreach ($values as $optionId => $content) {
33
+ $itemNode = $this->_contentInstance->getXmlInstance()->createElement('item');
34
+
35
+ $contentTextNode = $this->_contentInstance->getXmlInstance()->createCDATASection($content);
36
+
37
+ $itemNode->setAttribute('option_id', $optionId);
38
+
39
+ $itemNode->appendChild($contentTextNode);
40
+ $contentNode->appendChild($itemNode);
41
+ }
42
+
43
+ $this->_contentInstance->getСontentGroupNode()->appendChild($contentNode);
44
+
45
+ }
46
+ }
app/code/community/Smartling/Connector/Model/Types/Xml.php ADDED
@@ -0,0 +1,467 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Xml
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Model_Types_Xml
9
+ {
10
+
11
+ /**
12
+ *
13
+ * @var DOMElement
14
+ */
15
+ protected $_rootNode;
16
+
17
+ /**
18
+ *
19
+ * @var DOMElement
20
+ */
21
+ protected $_contentGroupNode;
22
+
23
+ /**
24
+ *
25
+ * @var string
26
+ */
27
+ protected $_contentNodeName;
28
+
29
+ /**
30
+ *
31
+ * @var string
32
+ */
33
+ protected $_rootNodeName;
34
+
35
+ /**
36
+ *
37
+ * @var string
38
+ */
39
+ protected $_contentGroupNodeName;
40
+
41
+ /**
42
+ *
43
+ * @var DOMDocument
44
+ */
45
+ protected $_xml;
46
+
47
+ /**
48
+ *
49
+ * @var array
50
+ */
51
+ protected $_params;
52
+
53
+ /**
54
+ *
55
+ * @var string
56
+ */
57
+ protected $_noTranslateComment = 'smartling.sltrans = notranslate';
58
+
59
+ /**
60
+ *
61
+ * @var string
62
+ */
63
+ protected $_translateComment = 'smartling.sltrans = translate';
64
+
65
+ /**
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_translatePaths = "smartling.translate_paths";
70
+
71
+ /**
72
+ *
73
+ * @var string
74
+ */
75
+ protected $_stringFormatPaths = "smartling.string_format_paths";
76
+
77
+ /**
78
+ * @var string
79
+ */
80
+ protected $_placeholderCustomName = "smartling.placeholder_format_custom";
81
+
82
+ /**
83
+ *
84
+ * @var array
85
+ */
86
+ protected $_customPlaceholder = array();
87
+
88
+ /**
89
+ *
90
+ * @var array
91
+ */
92
+ protected $_htmlContentNodeName = array();
93
+
94
+ /**
95
+ * init some actions
96
+ *
97
+ * @param array $params
98
+ */
99
+ public function __construct($params = array()) {
100
+ $this->_xml = new DOMDocument("1.0", "UTF-8");
101
+ $this->_params = $params;
102
+ $this->_setRootNode();
103
+ $this->_setContentGroupNode();
104
+ $this->_setContentNode();
105
+ $this->_initNodes();
106
+
107
+ $placeholder = '(?>\{\{)[^\{].+?(?>\}\})';
108
+ $this->addCustomPlaceholder($placeholder);
109
+ }
110
+
111
+ /**
112
+ * set content root node name
113
+ *
114
+ * @return void
115
+ */
116
+ protected function _setRootNode(){
117
+ if (isset($this->_params['root'])){
118
+ $this->_rootNodeName = $this->_params['root'];
119
+ } else {
120
+ $this->_rootNodeName = 'data';
121
+ }
122
+ }
123
+
124
+ /**
125
+ * set content group node name
126
+ *
127
+ * @return void
128
+ */
129
+ protected function _setContentGroupNode(){
130
+ if (isset($this->_params['content_group'])){
131
+ $this->_contentGroupNodeName = $this->_params['content_group'];
132
+ } else {
133
+ $this->_contentGroupNodeName = 'translate';
134
+ }
135
+ }
136
+
137
+ /**
138
+ * set content node name
139
+ *
140
+ * @return void
141
+ */
142
+ protected function _setContentNode(){
143
+ if (isset($this->_params['content'])){
144
+ $this->_contentNodeName = $this->_params['content'];
145
+ } else {
146
+ $this->_contentNodeName = 'content';
147
+ }
148
+ }
149
+
150
+ /**
151
+ * init root and group nodes
152
+ */
153
+ protected function _initNodes(){
154
+ $this->_rootNode = $this->_xml->createElement($this->_rootNodeName);
155
+ $this->_contentGroupNode = $this->_xml->createElement($this->_contentGroupNodeName);
156
+ }
157
+
158
+ /**
159
+ *
160
+ * @param array $params
161
+ */
162
+ public function setContentGroupAttribute($params = array()){
163
+ if (!empty($params)){
164
+ foreach ($params as $name => $value) {
165
+ $this->_contentGroupNode->setAttribute($name, $value);
166
+ }
167
+ }
168
+ }
169
+
170
+
171
+ /**
172
+ * set translate paths
173
+ *
174
+ * @return DOMElement
175
+ */
176
+ protected function _getTranslatePaths(){
177
+
178
+ $translatePaths = '';
179
+
180
+ $translatePathsItems[] = $this->_translatePaths . " = "
181
+ . $this->_rootNodeName . "/" . $this->_contentGroupNodeName
182
+ . "/" . $this->_contentNodeName;
183
+
184
+ if (!empty($this->_htmlContentNodeName)) {
185
+ $htmlNode = array_unique($this->_htmlContentNodeName);
186
+
187
+ foreach($htmlNode as $nodeName){
188
+ $translatePathsItems[] = $this->_rootNodeName . "/"
189
+ . $this->_contentGroupNodeName . "/"
190
+ . $nodeName;
191
+ }
192
+ }
193
+
194
+ $translatePaths .= implode(', ', $translatePathsItems);
195
+
196
+ $translatePathsComment = $this->_xml->createComment($translatePaths);
197
+ return $translatePathsComment;
198
+ }
199
+
200
+ /**
201
+ *
202
+ * @param string placeholder
203
+ */
204
+ public function addCustomPlaceholder($placeholder){
205
+ if (!empty($placeholder)){
206
+ $this->_customPlaceholder[] = $placeholder;
207
+ }
208
+ }
209
+
210
+ /**
211
+ *
212
+ * @return null | DOMElement
213
+ */
214
+ protected function _getCustomPlaceholder(){
215
+ if (sizeof($this->_customPlaceholder) > 0){
216
+ $customPlaceholder = $this->_placeholderCustomName . " = ";
217
+ for ($i = 0; $i < sizeof($this->_customPlaceholder); $i++){
218
+ $customPlaceholder .= $this->_customPlaceholder[$i];
219
+ }
220
+
221
+ $placeholderComment = $this->_xml->createComment($customPlaceholder);
222
+ return $placeholderComment;
223
+ }
224
+ return null;
225
+ }
226
+
227
+ /**
228
+ *
229
+ * @param string $content
230
+ * @param array $attribute
231
+ */
232
+ public function setTranslateContent($content, $attribute = array()){
233
+ $contentNode = $this->_xml->createElement($this->_contentNodeName);
234
+ if (!empty($attribute)){
235
+ foreach ($attribute as $name => $value) {
236
+ $contentNode->setAttribute($name, $value);
237
+ }
238
+ }
239
+
240
+ $contentTextNode = $this->_xml->createTextNode($content);
241
+ $contentNode->appendChild($contentTextNode);
242
+ $this->_contentGroupNode->appendChild($contentNode);
243
+ }
244
+
245
+ /**
246
+ *
247
+ * @param string $content
248
+ * @param array $attribute
249
+ * @return void
250
+ */
251
+ public function setNonTranslateContent($content, $attribute = array()){
252
+ $contentNode = $this->_xml->createElement($this->_contentNodeName);
253
+ if (!empty($attribute)){
254
+ foreach ($attribute as $name => $value) {
255
+ $contentNode->setAttribute($name, $value);
256
+ }
257
+ }
258
+
259
+ $contentTextNode = $this->_xml->createTextNode($content);
260
+ $contentNode->appendChild($contentTextNode);
261
+ $comment = $this->_xml->createComment($this->_noTranslateComment);
262
+ $this->_contentGroupNode->appendChild($comment);
263
+ $this->_contentGroupNode->appendChild($contentNode);
264
+ }
265
+
266
+ /**
267
+ *
268
+ * @return string
269
+ */
270
+ public function createContentFile(){
271
+ $this->_xml->appendChild($this->_getTranslatePaths());
272
+
273
+ if (!is_null($this->_getCustomPlaceholder())){
274
+ $this->_xml->appendChild($this->_getCustomPlaceholder());
275
+ }
276
+
277
+ if (!empty($this->_htmlContentNodeName)){
278
+ $this->_xml->appendChild($this->_getFormatPaths("html", $this->_htmlContentNodeName));
279
+ }
280
+
281
+ $this->_xml->appendChild($this->_rootNode);
282
+ $this->_rootNode->appendChild($this->_contentGroupNode);
283
+ return $this->_xml->saveXML();
284
+ }
285
+
286
+ /**
287
+ *
288
+ * @param string $filename
289
+ */
290
+ public function saveToFile($filename){
291
+ $this->_xml->save($filename);
292
+ }
293
+
294
+ /**
295
+ *
296
+ * @param string $type
297
+ * @param array $paths
298
+ */
299
+ protected function _getFormatPaths($type, $paths){
300
+ $formatPaths = $this->_stringFormatPaths . " = ";
301
+ for ($i = 0; $i < count($paths); $i++){
302
+ $formatPathsArray[] = $type . " : ". $this->_rootNodeName
303
+ . "/" . $this->_contentGroupNodeName
304
+ . "/" . $paths[$i];
305
+ }
306
+ $formatPathsArray = array_unique($formatPathsArray);
307
+ $formatPaths .= implode(', ', $formatPathsArray);
308
+ $translateFormatPaths = $this->_xml->createComment($formatPaths);
309
+ return $translateFormatPaths;
310
+ }
311
+
312
+ /**
313
+ *
314
+ * @param string $nodeName
315
+ * @param string $content
316
+ * @param array $attribute
317
+ */
318
+ public function setHtmlContent($nodeName, $content, $attribute = array()){
319
+ $this->_htmlContentNodeName[] = $nodeName;
320
+ $contentNode = $this->_xml->createElement($nodeName);
321
+ if (!empty($attribute)){
322
+ foreach ($attribute as $name => $value) {
323
+ $contentNode->setAttribute($name, $value);
324
+ }
325
+ }
326
+ $contentTextNode = $this->_xml->createCDATASection($content);
327
+ $contentNode->appendChild($contentTextNode);
328
+ $this->_contentGroupNode->appendChild($contentNode);
329
+ }
330
+
331
+ /**
332
+ *
333
+ * @param string $source
334
+ */
335
+ public function loadContent($source){
336
+ $this->_xml->loadXML($source);
337
+ return $this;
338
+ }
339
+
340
+ /**
341
+ * Return format capatible to save EAV attributes
342
+ * @return array
343
+ */
344
+ public function getAllData() {
345
+
346
+ $content = array();
347
+
348
+ $xpath = new DOMXPath($this->_xml);
349
+ $queryText = '//data/translate/content | '
350
+ . '//data/translate/htmlcontent';
351
+ $resultText = $xpath->query($queryText);
352
+
353
+ if(sizeof($resultText))
354
+ foreach($resultText as $element) {
355
+ $content[$element->getAttribute('attribute')] = $element->nodeValue;
356
+ }
357
+
358
+ $queryOptions = '//data/translate/select';
359
+ $resultOptions = $xpath->query($queryOptions);
360
+
361
+ if(sizeof($resultOptions))
362
+ foreach($resultOptions as $element) {
363
+ $items = array();
364
+ foreach($element->getElementsByTagName('item') as $item) {
365
+ $option_id = $item->getAttribute('option_id');
366
+ if(!is_numeric($option_id)) continue;
367
+ $items[] = (int)$option_id;
368
+ }
369
+
370
+ if(sizeof($items)) {
371
+ switch ($element->getAttribute('type')) {
372
+ case 'select':
373
+ $content[$element->getAttribute('attribute')] = $items[0];
374
+ break;
375
+ case 'multiselect':
376
+ default:
377
+ $content[$element->getAttribute('attribute')] = $items;
378
+ break;
379
+ }
380
+ }
381
+ }
382
+
383
+ return $content;
384
+ }
385
+
386
+ /**
387
+ * Return format to save attributes options
388
+ * @return array
389
+ */
390
+ public function getOptionsValues() {
391
+
392
+ $items = array();
393
+ $xpath = new DOMXPath($this->_xml);
394
+
395
+ $queryOptions = '//data/translate/select';
396
+ $resultOptions = $xpath->query($queryOptions);
397
+
398
+ if(sizeof($resultOptions))
399
+ foreach($resultOptions as $element) {
400
+
401
+ foreach($element->getElementsByTagName('item') as $item) {
402
+ $option_id = $item->getAttribute('option_id');
403
+ if(!is_numeric($option_id)) continue;
404
+
405
+ $items[$option_id] = array(
406
+ 'option_id' => (int)$option_id,
407
+ 'value' => $item->nodeValue
408
+ );
409
+ }
410
+
411
+ }
412
+
413
+
414
+ return $items;
415
+ }
416
+
417
+ /**
418
+ *
419
+ * @return array
420
+ * @deprecated since version 0.1.7
421
+ */
422
+ public function getContentElementsData(){
423
+ $content = array();
424
+ foreach ($this->_xml->getElementsByTagName($this->_contentNodeName) as $element) {
425
+ $content[$element->getAttribute('attribute')] = $element->nodeValue;
426
+ }
427
+ return $content;
428
+ }
429
+
430
+ /**
431
+ *
432
+ * @return array
433
+ * @deprecated since version 0.1.7
434
+ */
435
+ public function getHtmlContentElementData($nodeName){
436
+ $content = array();
437
+ foreach ($this->_xml->getElementsByTagName($nodeName) as $element) {
438
+ $content[$element->getAttribute('attribute')] = $element->nodeValue;
439
+ }
440
+ return $content;
441
+ }
442
+
443
+ /**
444
+ * Push node name to _htmlContentNodeName list
445
+ * @param type $nodeName
446
+ */
447
+ public function pushHtmlContentNodeName($nodeName) {
448
+ $this->_htmlContentNodeName[] = $nodeName;
449
+ }
450
+
451
+ /**
452
+ *
453
+ * @return DOMDocument
454
+ */
455
+ public function getXmlInstance() {
456
+ return $this->_xml;
457
+ }
458
+
459
+ /**
460
+ *
461
+ * @return DOMElement
462
+ */
463
+ public function getСontentGroupNode() {
464
+ return $this->_contentGroupNode;
465
+ }
466
+
467
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/AttributesController.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of IndexController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_AttributesController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ implements Smartling_Connector_Model_Translate_StatusInterface
11
+ {
12
+
13
+ protected function _initAction()
14
+ {
15
+ $this->loadLayout()
16
+ ->renderLayout();
17
+
18
+ return $this;
19
+ }
20
+
21
+ public function indexAction()
22
+ {
23
+ $this->productsAction();
24
+ }
25
+
26
+ public function productAction()
27
+ {
28
+ $this->_initAction();
29
+ }
30
+
31
+
32
+ public function categoryAction()
33
+ {
34
+ $this->_initAction();
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @return Zend_Controller_Response_Abstract
40
+ */
41
+ public function changeStatusAction() {
42
+
43
+ $requestData = $this->getRequest()->getParams();
44
+
45
+ $result = Mage::helper('connector')->changeStatus($requestData['type'],
46
+ $requestData['id'],
47
+ 'attributes',
48
+ 'attribute_id');
49
+
50
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
51
+ }
52
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/FieldsController.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of IndexController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_FieldsController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ implements Smartling_Connector_Model_Translate_StatusInterface
11
+ {
12
+
13
+ protected function _initAction()
14
+ {
15
+ $this->loadLayout()
16
+ ->renderLayout();
17
+ return $this;
18
+ }
19
+
20
+ public function indexAction()
21
+ {
22
+ $this->pagesAction();
23
+ }
24
+
25
+ public function pagesAction()
26
+ {
27
+ $this->_initAction();
28
+ }
29
+
30
+
31
+ public function blocksAction()
32
+ {
33
+ $this->_initAction();
34
+ }
35
+
36
+ /**
37
+ *
38
+ * @return Zend_Controller_Response_Abstract
39
+ */
40
+ public function changeStatusAction() {
41
+
42
+ $requestData = $this->getRequest()->getParams();
43
+
44
+ $result = Mage::helper('connector')->changeStatus($requestData['type'],
45
+ $requestData['id'],
46
+ 'fields',
47
+ 'field_name');
48
+
49
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
50
+ }
51
+
52
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/InstanceController.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of InstanceController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_InstanceController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+ /**
12
+ *
13
+ */
14
+ public function indexAction(){
15
+ $this->_redirect('edit');
16
+ }
17
+
18
+ /**
19
+ * edit or create new translations
20
+ */
21
+ public function editAction(){
22
+ $this->_title(Mage::helper('connector')->__('Create New Translation Content'));
23
+ $this->loadLayout();
24
+ $this->renderLayout();
25
+ }
26
+
27
+ /**
28
+ *
29
+ */
30
+ public function newAction(){
31
+ $this->_forward('edit');
32
+ }
33
+
34
+ /**
35
+ * show content grids
36
+ */
37
+ public function viewAction(){
38
+ $data = $this->getRequest()->getParams();
39
+
40
+ if (!$data['content_type']){
41
+ Mage::getSingleton('adminhtml/session')->addError(
42
+ Mage::helper('connector')->__('Please select Content Type'));
43
+ $this->_redirectReferer();
44
+ }
45
+
46
+ if (!isset($data['locales']) || !is_array($data['locales'])){
47
+ Mage::getSingleton('adminhtml/session')->addError(
48
+ Mage::helper('connector')->__('Please select locales'));
49
+ $this->_redirectReferer();
50
+ }
51
+
52
+ $contentTypeModel = Mage::getModel('connector/content_types')
53
+ ->load( (int) $data['content_type']);
54
+
55
+ if (!$contentTypeModel->getId()){
56
+ Mage::getSingleton('adminhtml/session')->addError(
57
+ Mage::helper('connector')->__('Unknown Content Type'));
58
+ $this->_forward("edit");
59
+ }
60
+
61
+ $website_id = $this->getRequest()->getParam('website_id');
62
+ Mage::register('sm_website_id', $website_id);
63
+
64
+ $contentType = Mage::getModel($contentTypeModel->getData('model'))
65
+ ->getContentTypeCode();
66
+
67
+ if (!$contentType || is_null($contentType)){
68
+ Mage::getSingleton('adminhtml/session')->addError(
69
+ Mage::helper('connector')->__('Unknown Content Type'));
70
+ $this->_forward("edit");
71
+ }
72
+
73
+ $gridBlock = "connector/adminhtml_content_{$contentType}";
74
+
75
+ $this->loadLayout();
76
+ $this->_addContent($this->getLayout()->createBlock($gridBlock));
77
+ $this->renderLayout();
78
+ }
79
+
80
+ /**
81
+ * Bulk upload single content to Smartling
82
+ * @TODO - implement facade pattern in method body
83
+ * @return void
84
+ */
85
+ public function confirmAction() {
86
+
87
+ $data = $this->getRequest()->getParams();
88
+
89
+ $countAddedItem = 0;
90
+
91
+ //[[ submition validation
92
+ $errors = array();
93
+ if (!isset($data['content_type']) || (string) $data['content_type'] === '') {
94
+ $errors[] = "Content type can't be empty";
95
+ }
96
+
97
+ $locales = $data['locales'];
98
+
99
+ if (!is_array($locales)) {
100
+ $errors[] = "Please specify locales";
101
+ }
102
+
103
+ try {
104
+
105
+ if (sizeof($errors)) {
106
+ Mage::throwException('Submission has errors');
107
+ }
108
+
109
+ $contentModelClass = Mage::getModel('connector/content_types')->load($data['content_type']);
110
+
111
+ if (!$contentModelClass->getId()) {
112
+ $message = Mage::helper('connector')->__("Unknown content type");
113
+ Mage::throwException($message);
114
+ }
115
+
116
+ $processData = array(
117
+ 'type' => $data['content_type']
118
+ );
119
+
120
+ $localeCodes = array();
121
+
122
+ /** @var Smartling_Connector_Model_Content_Abstract */
123
+ $projectsLocales = Mage::getModel('connector/projects_locales');
124
+
125
+ foreach($locales as $project_id => $locale) {
126
+
127
+ $processData['project_id'] = $project_id;
128
+
129
+ for ($i = 0; $i < sizeof($locale); $i++) {
130
+
131
+ $localeCode = $projectsLocales->getLocaleCodeByStoreId($locale[$i]);
132
+
133
+ if(!$localeCode) {
134
+ $errors[] = Mage::helper('connector')
135
+ ->__("Unknown locale ID - %s", $locale[$i]);
136
+ continue;
137
+ }
138
+
139
+ $localeCodes[$locale[$i]] = $localeCode;
140
+ }
141
+ }
142
+
143
+
144
+ //]] submition validation
145
+
146
+ $localesCounter = 0;
147
+ $alreadyAddedItem = 0;
148
+ foreach($locales as $project_id => $locale) {
149
+
150
+ $processData['project_id'] = $project_id;
151
+
152
+ for ($i = 0; $i < sizeof($locale); $i++) {
153
+
154
+ $localeCode = $localeCodes[$locale[$i]];
155
+ $localesCounter++;
156
+
157
+ foreach ($data['content'] as $origin_content_id) {
158
+
159
+ $processData['origin_content_id'] = $origin_content_id;
160
+
161
+ $result = Mage::getResourceModel('connector/content')
162
+ ->addSingleItem($locale[$i], $processData, true);
163
+
164
+ if ($result == '-1') {
165
+ $logMessage = Mage::helper('connector')
166
+ ->__('Atributes for translation are not specified');
167
+ Mage::helper('connector')->log($logMessage, Zend_log::ERR);
168
+ } elseif ($result && $result !== 0) {
169
+ $countAddedItem++;
170
+ } elseif ($result == 0) {
171
+ $logMessage = Mage::helper('connector')
172
+ ->__('Item already added in translation queue for locale "%s"', $localeCode);
173
+ $alreadyAddedItem++;
174
+ } else {
175
+ $logMessage = Mage::helper('connector')
176
+ ->__('Unable to add Item to translation queue for locale "%s"', $localeCode);
177
+ Mage::helper('connector')->log($logMessage, Zend_log::ERR);
178
+ }
179
+ }
180
+
181
+ }
182
+ }
183
+
184
+ // update content names
185
+ $typeName = $contentModelClass->getTypeName();
186
+ $contentModel = Mage::getModel('connector/content_' . $typeName);
187
+ $contentModel->saveNames();
188
+
189
+ //[[ submition report
190
+ $message = '';
191
+ if($countAddedItem > 1) {
192
+ $message = Mage::helper('connector')->__('Smartling Bulk Upload - %d nodes were added to queue', $countAddedItem);
193
+ } elseif($countAddedItem == 1) {
194
+ $message = Mage::helper('connector')->__('Smartling Bulk Upload - 1 node was added to queue');
195
+ } if(!$countAddedItem && $alreadyAddedItem) {
196
+ $message = Mage::helper('connector')->__('Smartling Bulk Upload - Submited items were added to to queue before.');
197
+ }
198
+
199
+ if($message) {
200
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
201
+ Mage::helper('connector')->log($message, Zend_log::INFO);
202
+ }
203
+
204
+ if($countAddedItem && $alreadyAddedItem) {
205
+ $message = Mage::helper('connector')->__('Some submited items were added to to queue before.');
206
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
207
+ Mage::helper('connector')->log($message, Zend_log::INFO);
208
+ }
209
+
210
+ if(($countAddedItem + $alreadyAddedItem) != (count($data['content']) * $localesCounter)) {
211
+ $message = Mage::helper('connector')
212
+ ->__('Some items were not added to submition. Please see log for more details.');
213
+ Mage::getSingleton('adminhtml/session')->addError($message);
214
+ Mage::helper('connector')->log($message, Zend_log::ERR);
215
+ }
216
+ //]] submition report
217
+
218
+ Mage::dispatchEvent('smartling_push_to_queue_after',
219
+ array(
220
+ 'model_instance' => $contentModel,
221
+ 'bulk_submit_content' => $data['content']
222
+ )
223
+ );
224
+
225
+ } catch (Mage_Core_Exception $e) {
226
+ $errors[] = $e->getMessage();
227
+ } catch (Exception $e) {
228
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
229
+ }
230
+
231
+ if (sizeof($errors) > 0) {
232
+ for ($i = sizeof($errors); $i--;) {
233
+ Mage::helper('connector')->log($errors[$i], Zend_log::ERR);
234
+ Mage::getSingleton('adminhtml/session')->addError($errors[$i]);
235
+ }
236
+ }
237
+
238
+ if($this->getRequest()->isAjax()) {
239
+ $this->loadLayout();
240
+
241
+ $block = $this->getLayout()->getMessagesBlock()->getGroupedHtml();
242
+ $result = array(
243
+ 'messageblock' => $block,
244
+ );
245
+
246
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
247
+ } else {
248
+ $this->_redirect('*/*/new');
249
+ }
250
+ }
251
+
252
+ /**
253
+ *
254
+ * @return \Mage_Core_Controller_Response_Http
255
+ */
256
+ public function profilesAction() {
257
+
258
+ $type = $this->getRequest()->getParam('type');
259
+ $filter_id = $this->getRequest()->getParam('filter_id');
260
+
261
+ $localesData = array(
262
+ 'entity_type' => $type,
263
+ 'filter_id' => $filter_id
264
+ );
265
+
266
+ $locales =
267
+ $this->getLayout()->createBlock('connector/adminhtml_projects_locales_form',
268
+ 'locales',
269
+ $localesData);
270
+
271
+ $html = $locales->toHtml()
272
+ . $locales->getScript();
273
+
274
+ if($locales->getReadyStatus()) {
275
+
276
+ $continue_button =
277
+ $this->getLayout()->createBlock('adminhtml/widget_button')
278
+ ->setData(array(
279
+ 'label' => Mage::helper('catalog')->__('Continue'),
280
+ 'type' => "button",
281
+ 'class' => 'save',
282
+ 'onclick' => $locales->getFormName() . 'Form.submit();'
283
+ ));
284
+ $html .= $continue_button->toHtml();
285
+
286
+ }
287
+
288
+ return $this->getResponse()->setBody($html);
289
+ }
290
+
291
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/ProjectsController.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of IndexController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_ProjectsController extends Mage_Adminhtml_Controller_Action
9
+ {
10
+
11
+ protected function _initProject() {
12
+ $project = Mage::getModel('connector/projects');
13
+ if ($id = $this->getRequest()->getParam('id')) {
14
+ $project->load($id);
15
+ } else { // set default value
16
+ $project->setRetrievalType(
17
+ Mage::helper('connector')->getDefaultRetrievalType()
18
+ );
19
+ $project->setActive(1);
20
+ $project->setApiUrl(Mage::getStoreConfig('connector/api_url'));
21
+ }
22
+
23
+
24
+ $localesData = Mage::getModel('connector/projects_locales')
25
+ ->getCollection()
26
+ ->addFieldToFilter('parent_id', $id);
27
+
28
+ $localesRegistryData = array();
29
+
30
+ foreach ($localesData as $locale) {
31
+ $localesRegistryData[$locale['store_id']] = $locale;
32
+ }
33
+
34
+ Mage::register('current_projects', $project);
35
+ Mage::register('current_projects_locales', $localesRegistryData);
36
+
37
+ return $project;
38
+ }
39
+
40
+ protected function _initAction() {
41
+ $this->_title($this->__('Smartling'))
42
+ ->_title($this->__('Projects'));
43
+
44
+ $this->loadLayout()->_setActiveMenu('smartling/projects');
45
+
46
+ return $this;
47
+ }
48
+
49
+ public function indexAction() {
50
+
51
+ $this->_initAction()
52
+ ->_addContent($this->getLayout()->createBlock('connector/adminhtml_projects'))
53
+ ->renderLayout();
54
+ }
55
+
56
+ public function newAction() {
57
+ $this->_initProject();
58
+ $this->loadLayout();
59
+ $this->renderLayout();
60
+ }
61
+
62
+ public function viewAction() {
63
+ $this->_forward('edit');
64
+ }
65
+
66
+ public function editAction() {
67
+
68
+ $data = $this->getRequest()->getParams();
69
+ $website_id = 0;
70
+ $this->_initProject();
71
+
72
+ if(isset($data['id']) && !empty($data['id'])) {
73
+ $project = Mage::registry('current_projects');
74
+ $website_id = $project->getData('website_id');
75
+ } elseif($data['website_id']) {
76
+ $website_id = $data['website_id'];
77
+ }
78
+
79
+ if(!$website_id || !is_numeric($website_id)) {
80
+ $errorMessage = Mage::helper('connector')->__('Please select website for profile');
81
+ Mage::getSingleton('adminhtml/session')->addError($errorMessage);
82
+ return $this->_redirect('*/*/');
83
+ }
84
+
85
+ Mage::register('website_id', $website_id);
86
+ $this->loadLayout();
87
+ $this->renderLayout();
88
+ }
89
+
90
+ public function saveAction() {
91
+
92
+ $data = $this->getRequest()->getPost();
93
+ $id = $this->getRequest()->getParam('id');
94
+
95
+
96
+ if (!empty($data)) {
97
+
98
+ try {
99
+
100
+ $locale_data = array();
101
+ $adapter = Mage::getModel('core/resource')->getConnection('write');
102
+
103
+ // select data for mapping
104
+ if (sizeof($data['is_enabled'])) {
105
+ foreach ($data['is_enabled'] as $key => $value) {
106
+
107
+ if (!$data['locale_code'][$key]) continue;
108
+
109
+ $locale_data[] = array(
110
+ 'store_id' => $key,
111
+ 'locale_code' => $data['locale_code'][$key],
112
+ 'id' => $data['project_locale_identity'][$key]
113
+ );
114
+ }
115
+ }
116
+
117
+ unset($data['is_enabled']);
118
+ unset($data['locale_code']);
119
+
120
+ if (!sizeof($locale_data)) {
121
+ Mage::throwException($this->__('You should choose at less one locale and enter appropriate Smartling locale code'));
122
+ }
123
+
124
+ if (!Mage::helper('connector')->validateProjectId($data['project_id'])){
125
+ Mage::throwException($this->__('Wrong projectId format'));
126
+ }
127
+
128
+ if (!Mage::helper('connector')->validateApiKey($data['key'])){
129
+ Mage::throwException($this->__('Wrong API key format'));
130
+ }
131
+
132
+ $adapter->beginTransaction();
133
+
134
+ // [[ update project main data
135
+ $projects = Mage::getModel('connector/projects');
136
+
137
+ $projects->setData($data);
138
+ if ($id) $projects->setId($id);
139
+
140
+ $projects->save();
141
+ // ]] update project main data
142
+
143
+
144
+ // [[ update project mapping data
145
+ $parent_id = $projects->getId();
146
+ $updatedLocalesIds = array();
147
+
148
+ foreach ($locale_data as $locale) {
149
+ $locale['parent_id'] = $parent_id;
150
+
151
+ $projectsLocales = Mage::getModel('connector/projects_locales');
152
+ if ($locale['id']) $projectsLocales->setId($locale['id']);
153
+ $projectsLocales->setData($locale)->save();
154
+
155
+ $updatedLocalesIds[] = $projectsLocales->getId();
156
+ }
157
+
158
+ $projectsLocalesTranslated = Mage::getModel('connector/projects_locales')
159
+ ->getCollection()
160
+ ->addFieldToFilter('parent_id', $parent_id)
161
+ ->addFieldToFilter('id', array('nin' => $updatedLocalesIds));
162
+
163
+ foreach ($projectsLocalesTranslated as $entity) {
164
+ $entity->delete();
165
+ }
166
+
167
+ // ]] update project mapping data
168
+
169
+ $adapter->commit();
170
+
171
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Data has been saved successfully'));
172
+
173
+ } catch (Mage_Core_Exception $e) { // validate
174
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
175
+ } catch (Exception $e) { // general error
176
+ $adapter->rollback();
177
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
178
+ }
179
+ }
180
+
181
+ $redirectBack = $this->getRequest()->getParam('back', false);
182
+
183
+ if ($redirectBack) {
184
+
185
+ if(is_object($projects)) {
186
+ $redirectProjectId = $projects->getId();
187
+ } elseif($id) {
188
+ $redirectProjectId = $id;
189
+ }
190
+
191
+ return $this->_redirect('*/*/edit', array(
192
+ 'id' => $redirectProjectId,
193
+ '_current' => true
194
+ ));
195
+ } else {
196
+ return $this->_redirect('*/*/');
197
+ }
198
+ }
199
+
200
+ public function deleteAction() {
201
+
202
+ $id = $this->getRequest()->getParam('id');
203
+
204
+ try {
205
+ Mage::getModel('connector/projects')->setId($id)->delete();
206
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Data has been removed successfully'));
207
+ } catch (Exception $e) { // general error
208
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
209
+ }
210
+
211
+ $this->_redirectReferer();
212
+ }
213
+
214
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/ServiceController.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Service
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_ServiceController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+
12
+ /**
13
+ *
14
+ * @return Mage_Adminhtml_Model_Session
15
+ */
16
+ protected function _getSession(){
17
+ return Mage::getSingleton('adminhtml/session');
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @return string (json)
23
+ */
24
+ public function configTestAction(){
25
+ $requestData = $this->getRequest()->getParams();
26
+ $errors = array();
27
+ $response = array();
28
+
29
+ if (!isset($requestData['apiKey']) || ($requestData['apiKey']) == ""){
30
+ $errors[] = Mage::helper('connector')->__('Please Enter Api key');
31
+ }
32
+
33
+ if (!isset($requestData['projectId']) || ($requestData['projectId']) == ""){
34
+ $errors[] = Mage::helper('connector')->__('Please Enter Project Id');
35
+ }
36
+
37
+ if (!Mage::helper('connector')->validateProjectId($requestData['projectId'])){
38
+ if(!$requestData['projectId']) {
39
+ $errors[] = Mage::helper('connector')->__('Project Id cannot be empty');
40
+ } else {
41
+ $errors[] = Mage::helper('connector')->__('Wrong projectId format. %s was entered', $requestData['projectId']);
42
+ }
43
+ }
44
+
45
+ if (!Mage::helper('connector')->validateApiKey($requestData['apiKey'])){
46
+ if(!$requestData['apiKey']) {
47
+ $errors[] = Mage::helper('connector')->__('API key cannot be empty');
48
+ } else {
49
+ $errors[] = Mage::helper('connector')->__('Wrong API key format. %s was entered', $requestData['apiKey']);
50
+ }
51
+ }
52
+
53
+
54
+ //try to check connection if errors empty
55
+ if (!sizeof($errors)){
56
+ $options = array(
57
+ 'apiKey' => $requestData['apiKey'],
58
+ 'projectId' => $requestData['projectId'],
59
+ );
60
+
61
+ try{
62
+ $translator = $this->_getTranslator($options);
63
+ $result = $translator->getTranslationsInfo(null, array('limit' => 1));
64
+ $result = $translator->convertResponse($result);
65
+ } catch (Exception $e){
66
+ $errors = $e->getMessage();
67
+ }
68
+ }
69
+
70
+ //define response depending from response or errors
71
+ if (sizeof($errors) > 0){
72
+ $response = array(
73
+ 'result' => 'ERROR',
74
+ 'message' => implode("; ", $errors),
75
+ );
76
+ } else {
77
+
78
+ if ($result->response->code == "SUCCESS"){
79
+ $response = array (
80
+ 'result' => 'SUCCESS',
81
+ 'message' => Mage::helper('connector')->__('Your credentials Successfully accepted'),
82
+ );
83
+ } else {
84
+ $response = array (
85
+ 'result' => 'ERROR',
86
+ 'message' => implode("; ", $result->response->messages),
87
+ );
88
+ }
89
+ }
90
+
91
+ $response = Mage::helper('core')->jsonEncode($response);
92
+ return $this->getResponse()->setBody($response);
93
+
94
+ }
95
+
96
+ /**
97
+ *
98
+ * @param array $options
99
+ * @return \Smartling_Connector_Model_Translator
100
+ */
101
+ protected function _getTranslator($options = array()){
102
+
103
+ // ini key for object pool if test new connection without real project
104
+ if(!isset($options['project_id'])) {
105
+ $options['project_id'] = 'no_profile_' . time();
106
+ }
107
+ $translator = Mage::getModel('connector/translator', $options);
108
+ $smartlingInstance = $translator->setSmartlingApiInstance($options);
109
+
110
+ return $smartlingInstance;
111
+ }
112
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CategoryController.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CategoryController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_Translator_CategoryController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+
12
+ /**
13
+ * show submissions in process
14
+ */
15
+ public function indexAction(){
16
+ $this->loadLayout();
17
+ $this->renderLayout();
18
+ }
19
+
20
+ /*
21
+ * use for Ajax only
22
+ */
23
+
24
+ public function gridAction(){
25
+ $this->getResponse()->setBody(
26
+ $this->getLayout()
27
+ ->createBlock('connector/adminhtml_content_category_grid')
28
+ ->toHtml()
29
+ );
30
+ }
31
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CmsBlockController.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of CmsBlockController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_Translator_CmsBlockController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+
12
+ public function indexAction(){
13
+ $this->loadLayout();
14
+ $this->renderLayout();
15
+ }
16
+
17
+ /*
18
+ * use for Ajax only
19
+ */
20
+
21
+ public function gridAction(){
22
+ $this->getResponse()->setBody(
23
+ $this->getLayout()->createBlock('connector/adminhtml_content_cmsBlock_grid')
24
+ ->toHtml()
25
+ );
26
+ }
27
+
28
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/CmsPageController.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Description of CmsPageController
6
+ *
7
+ * @author snail
8
+ */
9
+ class Smartling_Connector_Adminhtml_Translator_CmsPageController
10
+ extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ public function indexAction(){
14
+ $this->loadLayout();
15
+ // var_dump(Mage::getSingleton('core/layout')->getUpdate()->getHandles());
16
+ // die();
17
+ $this->renderLayout();
18
+ }
19
+
20
+ /*
21
+ * use for Ajax only
22
+ */
23
+
24
+ public function gridAction(){
25
+ $this->getResponse()->setBody(
26
+ $this->getLayout()->createBlock('connector/adminhtml_content_cmsPage_grid')
27
+ ->toHtml()
28
+ );
29
+ }
30
+
31
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/LocalizationController.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Description of LocalizationController
6
+ *
7
+ * @author smartling
8
+ */
9
+ class Smartling_Connector_Adminhtml_Translator_LocalizationController
10
+ extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ public function indexAction(){
14
+ $this->loadLayout();
15
+ $this->renderLayout();
16
+ }
17
+
18
+ /*
19
+ * use for Ajax only
20
+ */
21
+
22
+ public function gridAction(){
23
+ $this->getResponse()->setBody(
24
+ $this->getLayout()->createBlock('connector/adminhtml_content_localization_grid')
25
+ ->toHtml()
26
+ );
27
+ }
28
+
29
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/Translator/ProductController.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of ProductController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_Adminhtml_Translator_ProductController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+
12
+ public function indexAction(){
13
+ $this->loadLayout();
14
+ $this->renderLayout();
15
+ }
16
+
17
+ /*
18
+ * use for Ajax only
19
+ */
20
+
21
+ public function gridAction(){
22
+ $this->getResponse()->setBody(
23
+ $this->getLayout()->createBlock('connector/adminhtml_content_product_grid')
24
+ ->toHtml()
25
+ );
26
+ }
27
+ }
app/code/community/Smartling/Connector/controllers/Adminhtml/TranslatorController.php ADDED
@@ -0,0 +1,616 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of Translator
5
+ *
6
+ * @author Itdelight
7
+ */
8
+ class Smartling_Connector_Adminhtml_TranslatorController
9
+ extends Mage_Adminhtml_Controller_Action
10
+ {
11
+
12
+ public function indexAction() {
13
+ $this->_redirect('*/*/send');
14
+ }
15
+
16
+ /**
17
+ * needs for tet
18
+ */
19
+ public function allAction(){
20
+ $this->loadLayout();
21
+ $this->renderLayout();
22
+ }
23
+
24
+ /**
25
+ * shows log file with actions
26
+ */
27
+ public function logsAction() {
28
+ $this->loadLayout();
29
+ $this->renderLayout();
30
+ }
31
+
32
+ /**
33
+ * Download log file if exists
34
+ */
35
+ public function downloadlogAction(){
36
+
37
+ $filename = Mage::getBaseDir('var') . DS . 'log' . DS . Mage::getStoreConfig('dev/smartling/log_file');
38
+
39
+ if(!file_exists($filename)) {
40
+ $this->_redirectReferer();
41
+ }
42
+
43
+ $content = file_get_contents($filename);
44
+ $basename = basename($filename);
45
+
46
+ header('Content-disposition: attachment; filename=' . $basename);
47
+ header('Content-type: text/plain');
48
+ echo $content;
49
+
50
+ exit();
51
+ }
52
+
53
+ /**
54
+ * Download log file if exists
55
+ */
56
+ public function removelogAction(){
57
+
58
+ $filename = Mage::getBaseDir('var') . DS . 'log' . DS . Mage::getStoreConfig('dev/smartling/log_file');
59
+
60
+ if(file_exists($filename)) {
61
+
62
+ try {
63
+
64
+ if(!unlink($filename)) {
65
+ Mage::throwException("Sorry. File can't be removed. See exception log for more details.");
66
+ }
67
+
68
+ Mage::getSingleton('adminhtml/session')->addSuccess(
69
+ Mage::helper('connector')->__("Log file has been removed successfully.")
70
+ );
71
+
72
+ } catch (Mage_Core_Exception $ex) {
73
+
74
+ Mage::getSingleton('adminhtml/session')->addError(
75
+ Mage::helper('connector')->__($ex->getMessage())
76
+ );
77
+
78
+ Mage::logException($ex);
79
+ Mage::helper('connector')->log($ex->getMessage(), Zend_log::ERR);
80
+ }
81
+
82
+ }
83
+
84
+ $this->_redirectReferer();
85
+ }
86
+
87
+ /**
88
+ * show logs with errors
89
+ */
90
+ public function errorsAction(){
91
+ $this->loadLayout();
92
+ $this->getLayout()->getBlock('actions.logs')->setFilename('Response.log');
93
+ $this->renderLayout();
94
+ }
95
+
96
+ /**
97
+ * use for Ajax only
98
+ */
99
+ public function gridAction(){
100
+ $this->getResponse()->setBody(
101
+ $this->getLayout()->createBlock('connector/adminhtml_content_grid')
102
+ ->toHtml()
103
+ );
104
+ }
105
+
106
+ /**
107
+ * download file
108
+ */
109
+ public function downloadAction() {
110
+ $contentId = $this->getRequest()->getParam('content_id');
111
+
112
+ $errors = array();
113
+ if (!$contentId || (string) $contentId === '') {
114
+ $errors[] = "You have to specify content item first";
115
+ }
116
+
117
+ $projectsLocales = Mage::getModel('connector/projects_locales');
118
+
119
+ try {
120
+
121
+ if (sizeof($errors)) {
122
+ Mage::throwException('Submission has errors');
123
+ }
124
+
125
+ //@TODO add validation for projects IDs here
126
+
127
+ try {
128
+ $this->updateStatus($contentId);
129
+ } catch (Exception $e) {
130
+ $errors[] = $e->getMessage();
131
+ }
132
+
133
+ } catch (Mage_Core_Exception $e) {
134
+ $errors[] = $e->getMessage();
135
+ } catch (Exception $e) {
136
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
137
+ }
138
+
139
+ if (sizeof($errors) > 0) {
140
+ for ($i = sizeof($errors); $i--;) {
141
+ Mage::getSingleton('adminhtml/session')->addError($errors[$i]);
142
+ }
143
+ }
144
+
145
+ if($this->getRequest()->isAjax()) {
146
+ $this->loadLayout();
147
+
148
+ $block = $this->getLayout()->getMessagesBlock()->getGroupedHtml();
149
+ $result = array(
150
+ 'messageblock' => $block,
151
+ );
152
+
153
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
154
+ } else {
155
+ $this->_redirectReferer();
156
+ }
157
+ }
158
+
159
+ /**
160
+ * We need:
161
+ * - find items in smartling translation table (connector/content)
162
+ * foreach item:
163
+ * - if items locale is in locales array try do download content from Smartling API (connector/translator)
164
+ * - if content isn't null - create new content item (connector/content_abstract)
165
+ * - after that we need to update table with new content id (connector/content)
166
+ */
167
+ public function downloadsingleAction() {
168
+
169
+ $data = $this->getRequest()->getParams();
170
+ $origin_content_id = $data['content_id'];
171
+ $errors = array();
172
+ $locales = array();
173
+
174
+ if (!isset($data['content_type']) || (string) $data['content_type'] === '') {
175
+ $errors[] = Mage::helper('connector')->__("Content type can't be empty");
176
+ }
177
+
178
+ if(isset($data['locales'])) {
179
+ $locales = $data['locales'];
180
+ }
181
+
182
+ if (!sizeof($locales)) {
183
+ $errors[] = Mage::helper('connector')->__("Please specify locales");
184
+ }
185
+
186
+ if (!isset($data['content_id']) || (string) $data['content_id'] === '') {
187
+ $errors[] = Mage::helper('connector')->__("You have to specify content item first");
188
+ } else { // check if record is ready to apply translated content
189
+
190
+ $contentModel = Mage::getModel('connector/content');
191
+
192
+ foreach($locales as $project_id => $locale) {
193
+ for ($i = 0; $i < sizeof($locale); $i++) {
194
+
195
+ $locale_name = Mage::getSingleton('connector/projects')->getLocaleTitle($locale[$i]);
196
+
197
+ $contentcollection = $contentModel->getCollectionByUniqueKeys($origin_content_id, $project_id, $locale[$i]);
198
+ $item = $contentcollection->getFirstItem();
199
+
200
+ if(!sizeof($item->getData())) {
201
+ $errors[] = Mage::helper('connector')->__("Sorry, content not found in submission queue. Locale [%s]", $locale_name);
202
+ continue;
203
+ }
204
+
205
+ $checkStatusErrors = $contentModel->checkReadyForDownload($item->getStatus(), $locale_name);
206
+
207
+ if(sizeof($checkStatusErrors)) {
208
+ $errors = array_merge($errors, $checkStatusErrors);
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ $projectsLocales = Mage::getModel('connector/projects_locales');
215
+
216
+ try {
217
+
218
+ if (sizeof($errors)) {
219
+ Mage::throwException(
220
+ Mage::helper('connector')->__('Submission has errors')
221
+ );
222
+ }
223
+
224
+ foreach($locales as $project_id => $locale) {
225
+ for ($i = 0; $i < sizeof($locale); $i++) {
226
+
227
+ try {
228
+
229
+ $localeCode = $projectsLocales->getLocaleCodeByStoreId($locale[$i]);
230
+
231
+ if(!$localeCode) {
232
+ $message = Mage::helper('connector')
233
+ ->__("Unknown locale ID - %s", $locale[$i]);
234
+ throw new Exception($message);
235
+ }
236
+
237
+ $serviceModel = Mage::getModel('connector/service');
238
+ $serviceModel->setOriginContentId($origin_content_id);
239
+ $serviceModel->setProjectId($project_id);
240
+ $serviceModel->setStoreId($locale[$i]);
241
+
242
+ $result = $serviceModel->updateStatus(true);
243
+
244
+ if($result) {
245
+ Mage::getSingleton('adminhtml/session')->addSuccess(
246
+ Mage::helper('connector')->__("Content for locale %s has been successfully applied", $localeCode)
247
+ );
248
+ } else {
249
+ Mage::getSingleton('adminhtml/session')->addError(
250
+ Mage::helper('connector')->__("Content for locale %s has not translated yet", $localeCode)
251
+ );
252
+ }
253
+
254
+ } catch (Exception $e) {
255
+ $errors[] = $e->getMessage();
256
+ }
257
+
258
+ }
259
+ }
260
+
261
+
262
+ } catch (Mage_Core_Exception $e) {
263
+ $errors[] = $e->getMessage();
264
+ } catch (Exception $e) {
265
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
266
+ }
267
+
268
+ if (sizeof($errors) > 0) {
269
+ foreach($errors as $error) {
270
+ Mage::helper('connector')->log('Download single action. ' . $error, Zend_log::ERR);
271
+ Mage::getSingleton('adminhtml/session')->addError($error);
272
+ }
273
+ }
274
+
275
+ if($this->getRequest()->isAjax()) {
276
+
277
+ $this->loadLayout();
278
+
279
+ $block = $this->getLayout()->getMessagesBlock()->getGroupedHtml();
280
+ $result = array(
281
+ 'messageblock' => $block,
282
+ );
283
+
284
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
285
+ } else {
286
+ $this->_redirectReferer();
287
+ }
288
+ }
289
+
290
+ /**
291
+ * update file content status
292
+ * check comoletion process
293
+ */
294
+ public function updateAction(){
295
+ $content = $this->getRequest()->getParam('content');
296
+ $errors = array();
297
+
298
+ if (!is_array($content)){
299
+ Mage::getSingleton('adminhtml/session')->addError(
300
+ Mage::helper('connector')->__('Incorrect data type')
301
+ );
302
+ $this->_redirectReferer();
303
+ return;
304
+ }
305
+
306
+ $count = sizeof($content);
307
+
308
+ for ($i = 0; $i < $count; $i++){
309
+ try {
310
+ $this->updateStatus($content[$i]);
311
+ } catch (Exception $e) {
312
+ $errors[] = $e->getMessage();
313
+ }
314
+ }
315
+
316
+ $contentModel = Mage::getModel('connector/content');
317
+
318
+ if (!empty($errors)) {
319
+ Mage::getSingleton('adminhtml/session')->addError(implode("; ", array_unique($errors)));
320
+ }
321
+ $this->_redirectReferer();
322
+ return;
323
+ }
324
+
325
+ /**
326
+ * Upload single content to Smartling
327
+ *
328
+ * @return void
329
+ */
330
+ public function uploadsingleAction() {
331
+ $data = $this->getRequest()->getParams();
332
+
333
+ $countAddedItem = 0;
334
+ $locales = array();
335
+ $message = '';
336
+
337
+ $errors = array();
338
+ if (!isset($data['content_type']) || (string) $data['content_type'] === '') {
339
+ $errors[] = Mage::helper('connector')->__("Content type can't be empty");
340
+ }
341
+
342
+ if (!isset($data['content_id']) || (string) $data['content_id'] === '') {
343
+ $errors[] = Mage::helper('connector')->__("You have to specify content item first");
344
+ }
345
+
346
+ if(isset($data['locales'])) {
347
+ $locales = $data['locales'];
348
+ }
349
+
350
+ if (!is_array($locales)) {
351
+ $errors[] = Mage::helper('connector')->__("Please specify locales");
352
+ }
353
+
354
+ try {
355
+
356
+ if (sizeof($errors)) {
357
+ Mage::throwException(
358
+ Mage::helper('connector')->__('Submission has errors')
359
+ );
360
+ }
361
+
362
+ //@TODO add validation for projects IDs here
363
+
364
+
365
+ $contentModelClass = Mage::getModel('connector/content_types')->load($data['content_type']);
366
+ if (!$contentModelClass->getId()) {
367
+ $message = Mage::helper('connector')->__("Unknown content type");
368
+ Mage::throwException($message);
369
+ }
370
+
371
+ /** @var Smartling_Connector_Model_Content_Abstract */
372
+ $contentModel = Mage::getModel($contentModelClass->getModel());
373
+ $projectsLocales = Mage::getModel('connector/projects_locales');
374
+
375
+ $processData = array(
376
+ 'type' => $data['content_type'],
377
+ 'origin_content_id' => $data['content_id']
378
+ );
379
+
380
+ foreach($locales as $project_id => $locale) {
381
+
382
+ $processData['project_id'] = $project_id;
383
+
384
+ for ($i = 0; $i < sizeof($locale); $i++) {
385
+
386
+ try {
387
+
388
+ $localeCode = $projectsLocales->getLocaleCodeByStoreId($locale[$i]);
389
+
390
+ if(!$localeCode) {
391
+ $message = Mage::helper('connector')
392
+ ->__("Unknown locale ID - %s", $locale[$i]);
393
+ throw new Exception($message);
394
+ }
395
+
396
+ $result = Mage::getResourceModel('connector/content')
397
+ ->addSingleItem($locale[$i], $processData);
398
+
399
+ if ($result == '-1') {
400
+ $message = Mage::helper('connector')
401
+ ->__('Attributes for translation are not specified');
402
+ Mage::getSingleton('adminhtml/session')->addError($message);
403
+ } elseif ($result && $result !== 0) {
404
+ $message = Mage::helper('connector')
405
+ ->__('New item added in translation queue for locale "%s"', $localeCode);
406
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
407
+ $countAddedItem++;
408
+ } elseif ($result == 0) {
409
+ $message = Mage::helper('connector')
410
+ ->__('Item already added in translation queue for locale "%s"', $localeCode);
411
+ Mage::getSingleton('adminhtml/session')->addSuccess($message);
412
+ } else {
413
+ $message = Mage::helper('connector')
414
+ ->__('Unable to add Item to translation queue for locale "%s"', $localeCode);
415
+ throw new Exception($message);
416
+ }
417
+
418
+ } catch (Exception $e) {
419
+ $errors[] = $e->getMessage();
420
+ }
421
+
422
+ }
423
+ }
424
+
425
+ Mage::dispatchEvent('smartling_push_to_queue_after', array('model_instance' => $contentModel));
426
+
427
+ } catch (Mage_Core_Exception $e) {
428
+ $errors[] = $e->getMessage();
429
+ } catch (Exception $e) {
430
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
431
+ }
432
+
433
+ if (sizeof($errors) > 0) {
434
+ for ($i = sizeof($errors); $i--;) {
435
+ Mage::helper('connector')->log($errors[$i], Zend_log::ERR);
436
+ Mage::getSingleton('adminhtml/session')->addError($errors[$i]);
437
+ }
438
+ } elseif(Mage::getStoreConfig('dev/smartling/mode') == 1) {
439
+ Mage::helper('connector')->scheduleNow();
440
+ }
441
+
442
+ $this->loadLayout();
443
+ $block = $this->getLayout()->getMessagesBlock()->getGroupedHtml();
444
+ $result = array(
445
+ 'messageblock' => $block,
446
+ );
447
+
448
+ if($countAddedItem > 1) {
449
+ $message = Mage::helper('connector')->__('Smartling Upload Single - %d nodes were added to queue', $countAddedItem);
450
+ } elseif($countAddedItem == 1) {
451
+ $message = Mage::helper('connector')->__('Smartling Upload Single - 1 node was added to queue');
452
+ }
453
+
454
+ Mage::helper('connector')->log($message, Zend_log::INFO);
455
+
456
+ if($this->getRequest()->isAjax()) {
457
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
458
+ } else {
459
+ $this->_redirectReferer();
460
+ }
461
+ }
462
+
463
+ public function checkstatusAction() {
464
+
465
+ $data = $this->getRequest()->getParams();
466
+
467
+ // collection cache tag is harcoded in Mage_Core_Model_Resource_Db_Collection_Abstract extends Varien_Data_Collection_Db
468
+ $collection_cache_tag = 'collections';
469
+
470
+ $isCollectionCacheEnabled = Mage::app()->useCache($collection_cache_tag);
471
+ if($isCollectionCacheEnabled) {
472
+ $cacheKey = md5(serialize($data));
473
+ }
474
+
475
+ $result = array();
476
+ $errors = array();
477
+
478
+ try {
479
+
480
+ if (!isset($data['content_id']) || (string) $data['content_id'] === '') {
481
+ Mage::throwException(
482
+ Mage::helper('connector')->__("You have to specify content item first")
483
+ );
484
+ }
485
+
486
+ if($isCollectionCacheEnabled) {
487
+ $cachedData = Mage::app()->loadCache($cacheKey);
488
+
489
+ if($cachedData) {
490
+ $result = unserialize($cachedData);
491
+
492
+ if($this->getRequest()->isAjax()) {
493
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
494
+ }
495
+ }
496
+ }
497
+
498
+ $content_id = $data['content_id'];
499
+ $result['element_id'] = $content_id;
500
+
501
+ $contentCollection = Mage::getModel('connector/content')->getCollection();
502
+ $contentCollection->addIndentifyToFilter($content_id);
503
+ $contentCollection->addFieldToFilter('filename', array('neq' => ''));
504
+ $contentCollection->joinAdditionalDetails();
505
+
506
+ // if item is not uploaded
507
+ if($contentCollection->getSize() == 0) {
508
+ $result['percent'] = 0;
509
+
510
+ if($this->getRequest()->isAjax()) {
511
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
512
+ } else {
513
+ return false;
514
+ }
515
+ }
516
+
517
+ $item = $contentCollection->getFirstItem();
518
+
519
+ try {
520
+
521
+ $connector = Mage::getModel('connector/translator',
522
+ array(
523
+ 'apiKey' => $item['api_key'],
524
+ 'projectId' => $item['project_code'],
525
+ 'project_id' => $item['project_id']
526
+ )
527
+ );
528
+
529
+
530
+
531
+ // check status of translation
532
+ $statusResponse = $connector->checkStatus($item['filename'], $item['locale']);
533
+
534
+ // check of unexpected format
535
+ if (!Mage::helper('connector')->isJson($statusResponse)) {
536
+ Mage::throwException(
537
+ Mage::helper('connector')
538
+ ->__('Invalid response. Expected type is JSON. Received: ')
539
+ . $statusResponse
540
+ );
541
+ } else {
542
+ $statusResponseData = json_decode($statusResponse, true);
543
+ $responseData = array();
544
+
545
+ if(isset($statusResponseData['response'])) {
546
+ $responseData = $statusResponseData['response'];
547
+ }
548
+
549
+ if(isset($responseData['messages']) && $responseData['code'] != 'SUCCESS') {
550
+ Mage::throwException(implode('; ', $responseData['messages']));
551
+ }
552
+
553
+ $percent =
554
+ Mage::helper('connector')->calculatePercent(
555
+ @$responseData['data']['completedStringCount'],
556
+ @$responseData['data']['stringCount']
557
+ );
558
+
559
+ $result['percent'] = $percent;
560
+ }
561
+
562
+
563
+ } catch (Mage_Core_Exception $e) {
564
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
565
+ } catch (Exception $e) {
566
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
567
+ }
568
+
569
+ } catch (Mage_Core_Exception $e) {
570
+ $errors[] = $e->getMessage();
571
+ } catch (Exception $e) {
572
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
573
+ }
574
+
575
+ if (sizeof($errors) > 0) {
576
+ for ($i = sizeof($errors); $i--;) {
577
+ Mage::helper('connector')->log($errors[$i], Zend_log::ERR);
578
+ }
579
+ }
580
+
581
+ if($isCollectionCacheEnabled) {
582
+ Mage::app()->saveCache(serialize($result), $cacheKey,
583
+ array($collection_cache_tag),
584
+ Mage::getStoreConfig('dev/smartling/cache_statuses_life_time')
585
+ );
586
+ }
587
+
588
+
589
+ if($this->getRequest()->isAjax()) {
590
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
591
+ }
592
+ }
593
+
594
+ /**
595
+ * Call update status request
596
+ * @param int $content_id
597
+ * @return boolean
598
+ */
599
+ protected function updateStatus($content_id) {
600
+ $serviceModel = Mage::getModel('connector/service');
601
+ $serviceModel->setContentId($content_id);
602
+ $result = $serviceModel->updateStatus(true);
603
+
604
+ if($result) {
605
+ Mage::getSingleton('adminhtml/session')->addSuccess(
606
+ Mage::helper('connector')->__("Content has been successfully applied")
607
+ );
608
+ return true;
609
+ } else {
610
+ Mage::getSingleton('adminhtml/session')->addError(
611
+ Mage::helper('connector')->__("Content has not translated yet")
612
+ );
613
+ return false;
614
+ }
615
+ }
616
+ }
app/code/community/Smartling/Connector/controllers/ServiceController.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of ServiceController
5
+ *
6
+ * @author Smartling
7
+ */
8
+ class Smartling_Connector_ServiceController
9
+ extends Mage_Core_Controller_Front_Action
10
+ {
11
+
12
+ /**
13
+ * @deprecated since version 0.2.8
14
+ * @return void
15
+ */
16
+ public function uploadAction() {
17
+
18
+ $contentData = $this->getRequest()->getPost('content_data');
19
+
20
+ $errors = array();
21
+ $messages = array();
22
+ $result = array('status' => 0);
23
+
24
+ if (!$contentData) {
25
+ $errors[] = "Request has no parameters";
26
+ }
27
+
28
+ try {
29
+
30
+ if (sizeof($errors)) {
31
+ Mage::throwException('Submission has errors');
32
+ }
33
+
34
+ $item = unserialize($contentData);
35
+
36
+ if(!is_array($item) || !sizeof($item)) {
37
+ Mage::throwException('Data is empty');
38
+ }
39
+
40
+ /** @var $contentType Smartling_Connector_Model_Content */
41
+ $contentType = Mage::getModel('connector/content');
42
+
43
+
44
+
45
+ /** @var $contentModel Smartling_Connector_Model_Content_Abstract */
46
+ $contentModel = Mage::getModel($item['model']);
47
+
48
+ if(($contentModel instanceof Smartling_Connector_Model_Content_Abstract) == false) {
49
+ Mage::throwException("Application error. Model '{$item['model']}' does not of required type");
50
+ }
51
+
52
+ $instanceModel = $contentModel->getContentTypeEntityModel()
53
+ ->load($item['origin_content_id']);
54
+
55
+ if ($instanceModel->getId()) {
56
+ $content = $contentModel->createTranslateContent($instanceModel, $item['project_id'], $item['source_store_id']);
57
+
58
+ if(!$content || $content == '-1') {
59
+
60
+ $errMessage = "Upload content: Content is empty."
61
+ . " Content type: {$contentModel->getContentTypeCode()}."
62
+ . " Content id: {$instanceModel->getId()}";
63
+
64
+ Mage::throwException($errMessage);
65
+ }
66
+
67
+ $fileUri = ($item['filename']) ? $item['filename'] : $contentModel->getFileUri();
68
+
69
+ $responseSuccessStatus = $contentModel->uploadContent($content, $fileUri, $item);
70
+
71
+ } else {
72
+ $fileUri = $item['filename'];
73
+ }
74
+
75
+ if(!$item['filename']) {
76
+ $item['filename'] = $fileUri;
77
+ }
78
+
79
+ /**
80
+ * if successfully uploaded - update data in db about content item
81
+ */
82
+ if ($responseSuccessStatus) {
83
+ /**
84
+ * write event to logger
85
+ */
86
+ $message = Mage::helper('connector')->__('File "%s" for locale %s has been uploded',
87
+ $item['filename'],
88
+ $item['locales']);
89
+
90
+ $messages[] = $message;
91
+
92
+ Mage::helper('connector')->log($message, Zend_log::INFO);
93
+
94
+ $status = Smartling_Connector_Model_Content::CONTENT_STATUS_PROCESS;
95
+ $updateData = array('content_id' => $item['content_id'],
96
+ 'filename' => $item['filename'],
97
+ 'status' => $status,
98
+ 'content_title' => $contentModel->getContentTitle(),
99
+ 'locales' => $item['locales'],
100
+ 'origin_content_id' => $item['origin_content_id'],
101
+ 'project_id' => $item['project_id']
102
+ );
103
+ $contentType->setData($updateData);
104
+ try {
105
+ $contentType->save();
106
+ } catch (Mage_Exception $e){
107
+ Mage::helper('connector')->log($e->getMessage(), Zend_log::ERR);
108
+ Mage::throwException($e->getMessage());
109
+ }
110
+
111
+ } else {
112
+
113
+ $message = Mage::helper('connector')->__('Unable to upload "%s" for locale %s',
114
+ $contentModel->getFileUri(),
115
+ $item['locale']
116
+ );
117
+
118
+ Mage::helper('connector')->log($message, Zend_log::ERR);
119
+ Mage::throwException($message);
120
+ }
121
+
122
+ } catch (Mage_Core_Exception $e) {
123
+ $errors[] = $e->getMessage();
124
+ } catch (Exception $e) {
125
+ $errors[] = Mage::helper('connector')->__('Sorry. Internal application error.');
126
+ }
127
+
128
+ if(sizeof($errors)) {
129
+ Mage::helper('connector')->log(implode("\n", $errors), Zend_log::ERR);
130
+ $result['messages']['errors'] = $errors;
131
+ }
132
+
133
+ if(sizeof($messages)) {
134
+ $result['messages']['success'] = $messages;
135
+ }
136
+
137
+ if($this->getRequest()->isAjax()) {
138
+ return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
139
+ } else {
140
+ $this->_redirectReferer();
141
+ }
142
+ }
143
+ }
app/code/community/Smartling/Connector/etc/adminhtml.xml ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <menu>
5
+ <smartling translate="title" module="connector">
6
+ <title>Smartling</title>
7
+ <sort_order>70</sort_order>
8
+ <children>
9
+ <all_content translate="title" module="connector">
10
+ <title>Submissions</title>
11
+ <sort_order>0</sort_order>
12
+ <action>smartling/adminhtml_translator/all</action>
13
+ </all_content>
14
+ <instance translate="title" module="connector">
15
+ <title>Smartling Bulk Submit</title>
16
+ <sort_order>1</sort_order>
17
+ <action>smartling/adminhtml_instance/new</action>
18
+ </instance>
19
+ <logs translate="title" module="connector">
20
+ <title>Logs</title>
21
+ <sort_order>50</sort_order>
22
+ <action>smartling/adminhtml_translator/logs</action>
23
+ </logs>
24
+ </children>
25
+ </smartling>
26
+ <system>
27
+ <children>
28
+ <smartling translate="title">
29
+ <title>Smartling Settings</title>
30
+ <sort_order>95</sort_order>
31
+ <children>
32
+ <projects translate="title" module="connector">
33
+ <title>Settings Profiles</title>
34
+ <sort_order>1</sort_order>
35
+ <action>smartling/adminhtml_projects/index</action>
36
+ </projects>
37
+ <attributes translate="title" module="connector">
38
+ <title>Fields for Translation</title>
39
+ <sort_order>2</sort_order>
40
+ <children>
41
+ <products translate="title">
42
+ <title>Products Attributes</title>
43
+ <sort_order>1</sort_order>
44
+ <action>smartling/adminhtml_attributes/product</action>
45
+ </products>
46
+ <categories translate="title">
47
+ <title>Categories Attributes</title>
48
+ <sort_order>2</sort_order>
49
+ <action>smartling/adminhtml_attributes/category</action>
50
+ </categories>
51
+ <cms_pages translate="title">
52
+ <title>CMS Pages Fields</title>
53
+ <sort_order>3</sort_order>
54
+ <action>smartling/adminhtml_fields/pages</action>
55
+ </cms_pages>
56
+ <cms_blocks translate="title">
57
+ <title>CMS Blocks Fields</title>
58
+ <sort_order>4</sort_order>
59
+ <action>smartling/adminhtml_fields/blocks</action>
60
+ </cms_blocks>
61
+ </children>
62
+ </attributes>
63
+ </children>
64
+ </smartling>
65
+ </children>
66
+ </system>
67
+ </menu>
68
+ <acl>
69
+ <resources>
70
+ <all>
71
+ <title>Allow for All</title>
72
+ </all>
73
+ <admin>
74
+ <children>
75
+ <smartling module="connector">
76
+ <title>Smartling</title>
77
+ <sort_order>170</sort_order>
78
+ <children>
79
+ <all_content translate="title" module="connector">
80
+ <title>Submissions</title>
81
+ <sort_order>0</sort_order>
82
+ </all_content>
83
+ <instance translate="title" module="connector">
84
+ <title>Create new Translations</title>
85
+ <sort_order>1</sort_order>
86
+ </instance>
87
+ <logs translate="title" module="connector">
88
+ <title>Logs</title>
89
+ <sort_order>50</sort_order>
90
+ <children>
91
+ <action_logs translate="title" module="connector">
92
+ <title>Actions Log</title>
93
+ <sort_order>0</sort_order>
94
+ </action_logs>
95
+ </children>
96
+ </logs>
97
+ </children>
98
+ </smartling>
99
+ <system>
100
+ <children>
101
+ <config>
102
+ <children>
103
+ <smartling translate="title" module="connector">
104
+ <title>Smartling Section</title>
105
+ <sort_order>1</sort_order>
106
+ </smartling>
107
+ </children>
108
+ </config>
109
+ </children>
110
+ </system>
111
+ </children>
112
+ </admin>
113
+ </resources>
114
+ </acl>
115
+ </config>
app/code/community/Smartling/Connector/etc/config.xml ADDED
@@ -0,0 +1,315 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Smartling_Connector>
6
+ <version>1.0.0</version>
7
+ </Smartling_Connector>
8
+ </modules>
9
+ <global>
10
+ <blocks>
11
+ <connector>
12
+ <class>Smartling_Connector_Block</class>
13
+ </connector>
14
+ <adminhtml>
15
+ <rewrite>
16
+ <cms_block_edit_form>Smartling_Connector_Block_Adminhtml_Cms_Block_Edit_Form</cms_block_edit_form>
17
+ <system_store_edit_form>Smartling_Connector_Block_Adminhtml_Localization_Files_Edit_Form</system_store_edit_form>
18
+ </rewrite>
19
+ </adminhtml>
20
+ </blocks>
21
+ <helpers>
22
+ <connector>
23
+ <class>Smartling_Connector_Helper</class>
24
+ </connector>
25
+ </helpers>
26
+ <models>
27
+ <connector>
28
+ <class>Smartling_Connector_Model</class>
29
+ <resourceModel>connector_resource</resourceModel>
30
+ </connector>
31
+ <connector_resource>
32
+ <class>Smartling_Connector_Model_Resource</class>
33
+ <entities>
34
+ <translate_content>
35
+ <table>smartling_translate_content</table>
36
+ </translate_content>
37
+ <content_types>
38
+ <table>smartling_content_types</table>
39
+ </content_types>
40
+ <translate_attributes>
41
+ <table>smartling_translate_attributes</table>
42
+ </translate_attributes>
43
+ <translate_fields>
44
+ <table>smartling_translate_fields</table>
45
+ </translate_fields>
46
+ <projects>
47
+ <table>smartling_projects</table>
48
+ </projects>
49
+ <projects_locales>
50
+ <table>smartling_projects_locales</table>
51
+ </projects_locales>
52
+ <localization_files_index>
53
+ <table>smartling_localization_files_index</table>
54
+ </localization_files_index>
55
+ </entities>
56
+ </connector_resource>
57
+ </models>
58
+ <events>
59
+ <cms_page_save_after>
60
+ <observers>
61
+ <get_cmspage_info_after_save>
62
+ <type>singleton</type>
63
+ <class>Smartling_Connector_Model_Content_CmsPage_Observer</class>
64
+ <method>getPageInfo</method>
65
+ </get_cmspage_info_after_save>
66
+ </observers>
67
+ </cms_page_save_after>
68
+ <model_save_after>
69
+ <observers>
70
+ <send_cms_block_to_translator>
71
+ <type>singleton</type>
72
+ <class>Smartling_Connector_Model_Content_CmsBlock_Observer</class>
73
+ <method>sendBlockContentToTranslator</method>
74
+ </send_cms_block_to_translator>
75
+ </observers>
76
+ </model_save_after>
77
+ <catalog_product_prepare_save>
78
+ <observers>
79
+ <add_translate_options_to_product>
80
+ <type>singleton</type>
81
+ <class>Smartling_Connector_Model_Content_Product_Observer</class>
82
+ <method>addTranslationOptions</method>
83
+ </add_translate_options_to_product>
84
+ </observers>
85
+ </catalog_product_prepare_save>
86
+ <catalog_product_save_after>
87
+ <observers>
88
+ <send_product_content_to_translator>
89
+ <type>singleton</type>
90
+ <class>Smartling_Connector_Model_Content_Product_Observer</class>
91
+ <method>sendProductContentToTranslator</method>
92
+ </send_product_content_to_translator>
93
+ </observers>
94
+ </catalog_product_save_after>
95
+ <catalog_category_prepare_save>
96
+ <observers>
97
+ <add_translate_options_to_category>
98
+ <type>singleton</type>
99
+ <class>Smartling_Connector_Model_Content_Category_Observer</class>
100
+ <method>addTranslationOptions</method>
101
+ </add_translate_options_to_category>
102
+ </observers>
103
+ </catalog_category_prepare_save>
104
+ <catalog_category_save_after>
105
+ <observers>
106
+ <send_category_content_to_translator>
107
+ <type>singleton</type>
108
+ <class>Smartling_Connector_Model_Content_Category_Observer</class>
109
+ <method>sendCategoryContentToTranslator</method>
110
+ </send_category_content_to_translator>
111
+ </observers>
112
+ </catalog_category_save_after>
113
+ <adminhtml_catalog_category_tabs>
114
+ <observers>
115
+ <add_translation_tab>
116
+ <type>singleton</type>
117
+ <class>Smartling_Connector_Block_Adminhtml_Catalog_Category_Tab_Observer</class>
118
+ <method>addTranslationTab</method>
119
+ </add_translation_tab>
120
+ </observers>
121
+ </adminhtml_catalog_category_tabs>
122
+ <smartling_apply_content_after>
123
+ <observers>
124
+ <prepare_attributes_options>
125
+ <type>singleton</type>
126
+ <class>Smartling_Connector_Model_Service_Observer</class>
127
+ <method>prepareAttributesOptions</method>
128
+ </prepare_attributes_options>
129
+ </observers>
130
+ </smartling_apply_content_after>
131
+ <smartling_apply_content_after>
132
+ <observers>
133
+ <prepare_attributes_options>
134
+ <type>singleton</type>
135
+ <class>Smartling_Connector_Model_Service_Observer</class>
136
+ <method>updateTranslatedContentId</method>
137
+ </prepare_attributes_options>
138
+ </observers>
139
+ </smartling_apply_content_after>
140
+ <smartling_check_statuses_before>
141
+ <observers>
142
+ <join_files_path>
143
+ <class>Smartling_Connector_Model_Localization_Files_Observer</class>
144
+ <method>joinFilesPath</method>
145
+ </join_files_path>
146
+ </observers>
147
+ </smartling_check_statuses_before>
148
+ <smartling_check_statuses_after>
149
+ <observers>
150
+ <prepare_attributes_options>
151
+ <type>singleton</type>
152
+ <class>Smartling_Connector_Model_Service_Observer</class>
153
+ <method>importEavOptions</method>
154
+ </prepare_attributes_options>
155
+ <update_content_statuses>
156
+ <type>singleton</type>
157
+ <class>Smartling_Connector_Model_Service_Observer</class>
158
+ <method>updateContentStatuses</method>
159
+ </update_content_statuses>
160
+ </observers>
161
+ </smartling_check_statuses_after>
162
+ <smartling_push_to_queue_after>
163
+ <observers>
164
+ <fill_source_locale>
165
+ <type>singleton</type>
166
+ <class>Smartling_Connector_Model_Translator_Observer</class>
167
+ <method>fillSourceLocale</method>
168
+ </fill_source_locale>
169
+ <fill_title>
170
+ <class>Smartling_Connector_Model_Translator_Observer</class>
171
+ <method>fillTitles</method>
172
+ </fill_title>
173
+ <reset_changed_flag>
174
+ <class>Smartling_Connector_Model_Localization_Files_Observer</class>
175
+ <method>resetСhangedFlag</method>
176
+ </reset_changed_flag>
177
+ </observers>
178
+ </smartling_push_to_queue_after>
179
+ </events>
180
+ <resources>
181
+ <smartling_setup>
182
+ <setup>
183
+ <module>Smartling_Connector</module>
184
+ <class>Mage_Core_Model_Resource_Setup</class>
185
+ </setup>
186
+ </smartling_setup>
187
+ </resources>
188
+ </global>
189
+ <admin>
190
+ <routers>
191
+ <connector>
192
+ <use>admin</use>
193
+ <args>
194
+ <module>Smartling_Connector</module>
195
+ <frontName>smartling</frontName>
196
+ </args>
197
+ </connector>
198
+ </routers>
199
+ </admin>
200
+ <adminhtml>
201
+ <layout>
202
+ <updates>
203
+ <connector>
204
+ <file>smartling/translator.xml</file>
205
+ </connector>
206
+ </updates>
207
+ </layout>
208
+ </adminhtml>
209
+ <frontend>
210
+ <routers>
211
+ <connector>
212
+ <use>standard</use>
213
+ <args>
214
+ <module>Smartling_Connector</module>
215
+ <frontName>smartling</frontName>
216
+ </args>
217
+ </connector>
218
+ </routers>
219
+ </frontend>
220
+ <crontab>
221
+ <jobs>
222
+ <upload_bulk_content>
223
+ <schedule>
224
+ <cron_expr>*/5 * * * *</cron_expr>
225
+ </schedule>
226
+ <run>
227
+ <model>connector/service::callUpload</model>
228
+ </run>
229
+ </upload_bulk_content>
230
+ <check_statuses>
231
+ <schedule>
232
+ <cron_expr>* */3 * * *</cron_expr>
233
+ </schedule>
234
+ <run>
235
+ <model>connector/service::updateStatus</model>
236
+ </run>
237
+ </check_statuses>
238
+ <check_files>
239
+ <schedule>
240
+ <cron_expr>* */1 * * *</cron_expr>
241
+ </schedule>
242
+ <run>
243
+ <model>connector/localization_files_observer::checkFiles</model>
244
+ </run>
245
+ </check_files>
246
+ </jobs>
247
+ </crontab>
248
+ <default>
249
+ <dev>
250
+ <smartling>
251
+ <mock_data>0</mock_data>
252
+ <log_file>smartling.log</log_file>
253
+ <log_level>6</log_level>
254
+ <cache_statuses_life_time>600</cache_statuses_life_time>
255
+ </smartling>
256
+ </dev>
257
+ <connector>
258
+ <translate_attributes>
259
+ <catalog_product>
260
+ <small_image/>
261
+ <thumbnail/>
262
+ <url_key/>
263
+ <url_path/>
264
+ <image/>
265
+ <visibility/>
266
+ <custom_design/>
267
+ <custom_design_from/>
268
+ <custom_design_to/>
269
+ <custom_layout_update/>
270
+ <custom_use_parent_settings/>
271
+ <page_layout/>
272
+ </catalog_product>
273
+ <catalog_category>
274
+ <thumbnail/>
275
+ <url_key/>
276
+ <url_path/>
277
+ <image/>
278
+ <page_layout/>
279
+ <landing_page/>
280
+ <is_active/>
281
+ <display_mode/>
282
+ <default_sort_by/>
283
+ <custom_apply_to_products/>
284
+ <available_sort_by/>
285
+ <available_sort_by/>
286
+ <custom_design/>
287
+ <custom_design_from/>
288
+ <custom_design_to/>
289
+ <custom_layout_update/>
290
+ <custom_use_parent_settings/>
291
+ <filter_price_range/>
292
+ <include_in_menu/>
293
+ </catalog_category>
294
+ <cms_page>
295
+ <root_template/>
296
+ <layout_update_xml/>
297
+ <custom_theme/>
298
+ <custom_root_template/>
299
+ <custom_layout_update_xml/>
300
+ <identifier/>
301
+ </cms_page>
302
+ <cms_block>
303
+ <root_template/>
304
+ <layout_update_xml/>
305
+ <custom_theme/>
306
+ <custom_root_template/>
307
+ <custom_layout_update_xml/>
308
+ <identifier/>
309
+ </cms_block>
310
+ </translate_attributes>
311
+ <max_threads>5</max_threads>
312
+ <api_url>https://capi.smartling.com/v1</api_url>
313
+ </connector>
314
+ </default>
315
+ </config>
app/code/community/Smartling/Connector/etc/system.xml ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <tabs>
5
+ <smartling translate="label" module="connector">
6
+ <label>Smartling Translations</label>
7
+ <sort_order>400</sort_order>
8
+ </smartling>
9
+ </tabs>
10
+ <sections>
11
+ <smartling translate="label" module="connector">
12
+ <class>separator-top</class>
13
+ <label>Smartling Settings</label>
14
+ <tab>smartling</tab>
15
+ <sort_order>100</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <groups>
20
+ <settings translate="label" module="connector">
21
+ <label>Basic Settings</label>
22
+ <frontend_type>text</frontend_type>
23
+ <sort_order>10</sort_order>
24
+ <show_in_default>1</show_in_default>
25
+ <show_in_website>0</show_in_website>
26
+ <show_in_store>0</show_in_store>
27
+ <fields>
28
+ <test_connection translate="label" module="connector">
29
+ <label>Smartling Module Version</label>
30
+ <frontend_type>button</frontend_type>
31
+ <frontend_model>connector/adminhtml_system_config_version</frontend_model>
32
+ <sort_order>0</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>0</show_in_website>
35
+ <show_in_store>0</show_in_store>
36
+ </test_connection>
37
+ </fields>
38
+ </settings>
39
+ </groups>
40
+ </smartling>
41
+ <dev>
42
+ <groups>
43
+ <smartling>
44
+ <class>separator-top</class>
45
+ <label>Smartling Settings</label>
46
+ <tab>smartling</tab>
47
+ <sort_order>1020</sort_order>
48
+ <show_in_default>1</show_in_default>
49
+ <show_in_website>1</show_in_website>
50
+ <show_in_store>1</show_in_store>
51
+ <fields>
52
+ <mode translate="label" module="connector">
53
+ <label>Test Mode</label>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>adminhtml/system_config_source_yesno</source_model>
56
+ <sort_order>40</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <show_in_website>0</show_in_website>
59
+ <show_in_store>0</show_in_store>
60
+ <comment>Test mode uploads content automatically</comment>
61
+ </mode>
62
+ <mock_data translate="title" module="connector">
63
+ <label>Mock Data</label>
64
+ <frontend_type>select</frontend_type>
65
+ <source_model>adminhtml/system_config_source_yesno</source_model>
66
+ <sort_order>80</sort_order>
67
+ <show_in_default>1</show_in_default>
68
+ <show_in_website>0</show_in_website>
69
+ <show_in_store>0</show_in_store>
70
+ </mock_data>
71
+ <log_file translate="title" module="connector">
72
+ <label>Log File Name</label>
73
+ <frontend_type>text</frontend_type>
74
+ <sort_order>90</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
+ </log_file>
79
+ <log_level translate="title" module="connector">
80
+ <label>Log Level</label>
81
+ <frontend_type>select</frontend_type>
82
+ <source_model>Smartling_Connector_Model_Source_Log_Level</source_model>
83
+ <sort_order>100</sort_order>
84
+ <show_in_default>1</show_in_default>
85
+ <show_in_website>0</show_in_website>
86
+ <show_in_store>0</show_in_store>
87
+ </log_level>
88
+ <cache_statuses_life_time translate="title" module="connector">
89
+ <label>Grid Cache Queries Life Time</label>
90
+ <frontend_type>text</frontend_type>
91
+ <sort_order>120</sort_order>
92
+ <show_in_default>1</show_in_default>
93
+ <show_in_website>0</show_in_website>
94
+ <show_in_store>0</show_in_store>
95
+ </cache_statuses_life_time>
96
+ </fields>
97
+ </smartling>
98
+ </groups>
99
+ </dev>
100
+ </sections>
101
+ </config>
app/code/community/Smartling/Connector/sql/smartling_setup/install-1.0.0.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("DROP TABLE IF EXISTS smartling_content_types");
8
+ $installer->run("DROP TABLE IF EXISTS smartling_localization_files_index");
9
+ $installer->run("DROP TABLE IF EXISTS smartling_projects");
10
+ $installer->run("DROP TABLE IF EXISTS smartling_projects_locales");
11
+ $installer->run("DROP TABLE IF EXISTS smartling_translate_attributes");
12
+ $installer->run("DROP TABLE IF EXISTS smartling_translate_content");
13
+ $installer->run("DROP TABLE IF EXISTS smartling_translate_fields");
14
+
15
+ $indexColumns = array ('origin_content_id', 'type', 'project_id', 'store_id');
16
+ $processTable = $installer->getConnection()
17
+ ->newTable($installer->getTable('connector/translate_content'))
18
+ ->addColumn('content_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
19
+ 'unsigned' => true,
20
+ 'nullable' => false,
21
+ 'primary' => true,
22
+ 'identity' => true,
23
+ ), 'Content Id')
24
+ ->addColumn('type', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
25
+ 'unsigned' => true,
26
+ ), 'Content type')
27
+ ->addColumn('translated_content_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
28
+ 'unsigned' => true,
29
+ 'nullable' => true,
30
+ ), 'Translated Content ID')
31
+ ->addColumn('source_store_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
32
+ 'unsigned' => true,
33
+ 'nullable' => false,
34
+ ), 'Id of source store view')
35
+ ->addColumn('origin_content_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
36
+ 'unsigned' => true,
37
+ 'nullable' => false,
38
+ ), 'Origin Content Id')
39
+ ->addColumn('content_title', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
40
+ 'nullable' => false,
41
+ ), 'Content Title')
42
+ ->addColumn('filename', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
43
+ 'nullable' => false,
44
+ ), 'Filename')
45
+ ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
46
+ 'nullable' => false,
47
+ 'unsigned' => true,
48
+ ), 'Store Id')
49
+ ->addColumn('project_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
50
+ 'nullable' => false,
51
+ 'unsigned' => true
52
+ ), 'Magento Project Id')
53
+ ->addColumn('submitter', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
54
+ 'unsigned' => false
55
+ ), 'Username Id')
56
+ ->addColumn('submitted_time', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
57
+ 'nullable' => false,
58
+ 'default' => Varien_Db_Ddl_Table::TIMESTAMP_INIT,
59
+ ), 'Submitted for translate')
60
+ ->addColumn('percent', Varien_Db_Ddl_Table::TYPE_FLOAT, '4,2', array(
61
+ 'nullable' => true
62
+ ), 'Translated content percent')
63
+ ->addColumn('status', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
64
+ 'nullable' => true
65
+ ), 'Status of translated content')
66
+ ->addIndex($installer->getIdxName('connector/translate_content', $indexColumns, Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE),
67
+ $indexColumns, array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE));
68
+
69
+ $installer->getConnection()->createTable($processTable);
70
+
71
+ $typesTable = $installer->getConnection()
72
+ ->newTable($installer->getTable('connector/content_types'))
73
+ ->addColumn('type_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
74
+ 'unsigned' => true,
75
+ 'nullable' => false,
76
+ 'primary' => true,
77
+ 'identity' => true,
78
+ ), 'Content Id')
79
+ ->addColumn('type_name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
80
+ 'nullable' => false,
81
+ ), 'Type name')
82
+ ->addColumn('model', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
83
+ 'nullable' => false,
84
+ ), 'Model')
85
+ ->addColumn('title', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array(
86
+ 'nullable' => false,
87
+ ), 'Title');
88
+
89
+ $installer->getConnection()->createTable($typesTable);
90
+
91
+ $projectsTable = $installer->getTable('connector/projects');
92
+ $projectsLocalesTable = $installer->getTable('connector/projects_locales');
93
+
94
+ $table_projects = $installer->getConnection()->newTable($projectsTable)
95
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
96
+ 'identity' => true,
97
+ 'nullable' => false,
98
+ 'primary' => true,
99
+ ), 'Identity')
100
+ ->addColumn('website_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
101
+ 'nullable' => false,
102
+ 'unsigned' => true
103
+ ), 'Identity')
104
+ ->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
105
+ 'nullable' => false
106
+ ), 'Project Name')
107
+ ->addColumn('active', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
108
+ 'unsigned' => true,
109
+ 'nullable' => false
110
+ ), 'Is Active')
111
+ ->addColumn('api_url', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
112
+ 'nullable' => false
113
+ ), 'API url')
114
+ ->addColumn('callback_url', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
115
+ 'nullable' => true
116
+ ), 'Callback url')
117
+ ->addColumn('project_id', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
118
+ 'nullable' => false
119
+ ), 'Project identity')
120
+ ->addColumn('key', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
121
+ 'nullable' => false
122
+ ), 'API Key')
123
+ ->addColumn('retrieval_type', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
124
+ 'nullable' => false
125
+ ), 'Retrieval Type')
126
+ ->setComment('List of Smartling Projects');
127
+ $installer->getConnection()->createTable($table_projects);
128
+
129
+
130
+ $table_projects_locale = $installer->getConnection()->newTable($projectsLocalesTable)
131
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
132
+ 'identity' => true,
133
+ 'nullable' => false,
134
+ 'primary' => true,
135
+ ), 'Identity')
136
+ ->addColumn('parent_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
137
+ 'unsigned' => true,
138
+ 'nullable' => false
139
+ ), 'Parent Id')
140
+ ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
141
+ 'default' => 0
142
+ ), 'Store View')
143
+ ->addColumn('locale_code', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
144
+ 'nullable' => false
145
+ ), 'Smartling Locale Code')
146
+ ->setComment('List of Smartling Projects Locales')
147
+ ->addForeignKey(
148
+ $installer->getFkName('connector/projects_locales', 'projects_locales_id', 'connector/projects', 'id'),
149
+ 'parent_id', $projectsTable, 'id',
150
+ Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE
151
+ );
152
+
153
+ $installer->getConnection()->createTable($table_projects_locale);
154
+
155
+ $filesIndexTable = $installer->getConnection()
156
+ ->newTable($installer->getTable('connector/localization_files_index'))
157
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
158
+ 'identity' => true,
159
+ 'nullable' => false,
160
+ 'primary' => true,
161
+ ), 'Identity')
162
+ ->addColumn('dir_name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 16, array(
163
+ 'nullable' => false
164
+ ), 'Localization files dir name')
165
+ ->addColumn('file_path', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
166
+ 'nullable' => false
167
+ ), 'File Path')
168
+ ->addColumn('file_exists', Varien_Db_Ddl_Table::TYPE_SMALLINT, 1, array(
169
+ 'default' => 1
170
+ ), 'Flag if file exists')
171
+ ->addColumn('has_changed', Varien_Db_Ddl_Table::TYPE_SMALLINT, 1, array(
172
+ 'default' => 0
173
+ ), 'Flag if file has changed since previous indexing')
174
+ ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
175
+ ), 'Update Time')
176
+ ->addIndex(
177
+ $installer->getIdxName(
178
+ 'connector/localization_files_index',
179
+ array('dir_name', 'file_path'),
180
+ Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE
181
+ ),
182
+ array('dir_name', 'file_path'),
183
+ array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE))
184
+ ->setComment('List of locale files');
185
+ $installer->getConnection()->createTable($filesIndexTable);
186
+
187
+ $installer->getConnection()
188
+ ->addColumn($installer->getTable('core_store'), 'store_localization_dir',
189
+ array(
190
+ 'comment' => 'Localization dir name',
191
+ 'nullable' => true,
192
+ 'column_type' => Varien_Db_Ddl_Table::TYPE_TEXT,
193
+ 'length' => 16
194
+ )
195
+ );
196
+
197
+ $translateAttributesTable = $installer->getConnection()->newTable($installer->getTable('connector/translate_attributes'))
198
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
199
+ 'identity' => true,
200
+ 'nullable' => false,
201
+ 'primary' => true,
202
+ ), 'Record ID')
203
+ ->addColumn('attribute_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
204
+ 'unsigned' => true,
205
+ 'nullable' => false
206
+ ), 'Attribute ID')
207
+ ->addColumn('entity_type_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
208
+ 'unsigned' => true,
209
+ 'nullable' => false
210
+ ), 'Entity Type Id')
211
+ ->addIndex(
212
+ $installer->getIdxName(
213
+ 'connector/translate_attributes',
214
+ array('attribute_id', 'entity_type_id')
215
+ ),
216
+ array('attribute_id', 'entity_type_id'),
217
+ array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE)
218
+ )
219
+ ->setComment('List of attributes which should not be translated');
220
+ $installer->getConnection()->createTable($translateAttributesTable);
221
+
222
+ $translateFieldsTable = $installer->getConnection()->newTable($installer->getTable('connector/translate_fields'))
223
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
224
+ 'unsigned' => true,
225
+ 'nullable' => false,
226
+ 'primary' => true,
227
+ 'identity' => true,
228
+ ), 'Field Id')
229
+ ->addColumn('field_name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 64, array(
230
+ 'nullable' => false,
231
+ ), 'Field Name')
232
+ ->addColumn('entity_type_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
233
+ 'unsigned' => true,
234
+ 'nullable' => false
235
+ ), 'Smartling Entity Type Id')
236
+ ->addIndex(
237
+ $installer->getIdxName(
238
+ 'connector/translate_fields',
239
+ array('id', 'entity_type_id')
240
+ ),
241
+ array('id', 'entity_type_id'),
242
+ array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE)
243
+ )
244
+ ->setComment('List of columns in table which should not be translated');
245
+
246
+ $installer->getConnection()->createTable($translateFieldsTable);
247
+
248
+ $table = $installer->getTable('connector/content_types');
249
+ $data = array(
250
+ array(
251
+ 'type_id' => 1,
252
+ 'type_name' => Smartling_Connector_Model_Content_CmsPage::CONTENT_TYPE,
253
+ 'model' => 'connector/content_cmsPage',
254
+ 'title' => 'Pages'
255
+ ),
256
+ array(
257
+ 'type_id' => 2,
258
+ 'type_name' => Smartling_Connector_Model_Content_CmsBlock::CONTENT_TYPE,
259
+ 'model' => 'connector/content_cmsBlock',
260
+ 'title' => 'Static Blocks'
261
+ ),
262
+ array(
263
+ 'type_id' => 3,
264
+ 'type_name' => Smartling_Connector_Model_Content_Product::CONTENT_TYPE,
265
+ 'model' => 'connector/content_product',
266
+ 'title' => 'Products'
267
+ ),
268
+ array(
269
+ 'type_id' => 4,
270
+ 'type_name' => Smartling_Connector_Model_Content_Category::CONTENT_TYPE,
271
+ 'model' => 'connector/content_category',
272
+ 'title' => 'Categories'
273
+ ),
274
+ array(
275
+ 'type_id' => 5,
276
+ 'type_name' => Smartling_Connector_Model_Content_Attribute::CONTENT_TYPE,
277
+ 'model' => 'connector/content_attribute',
278
+ 'title' => 'Attributes'
279
+ ),
280
+ array(
281
+ 'type_id' => 6,
282
+ 'type_name' => Smartling_Connector_Model_Content_Localization::CONTENT_TYPE,
283
+ 'model' => 'connector/content_localization',
284
+ 'title' => 'Localization Files'
285
+ )
286
+ );
287
+
288
+ $installer->getConnection()->insertMultiple($table, $data);
289
+
290
+ $installer->endSetup();
291
+
app/design/adminhtml/default/default/layout/smartling/translator.xml ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <layout version="0.1.0">
4
+ <connector_adminhtml_translator_all>
5
+ <reference name="head">
6
+ <action method="addJs">
7
+ <file>smartling/check_statuses.js</file>
8
+ </action>
9
+ <action method="addCss">
10
+ <stylesheet>smartling/StyleSheet/bars.css</stylesheet>
11
+ </action>
12
+ </reference>
13
+ <reference name="content">
14
+ <block type="core/template" template="connector/adminhtml/widget/grid/scripts_wraper.phtml" name="grid_scripts_wraper"/>
15
+ <block type="connector/adminhtml_content" name="all.content" />
16
+ </reference>
17
+ </connector_adminhtml_translator_all>
18
+
19
+ <connector_adminhtml_translator_cmspage_index>
20
+ <reference name="content">
21
+ <block type = "connector/adminhtml_content_cmsPage" name = "cmspage.grid" />
22
+ </reference>
23
+ </connector_adminhtml_translator_cmspage_index>
24
+
25
+ <connector_adminhtml_translator_cmspage_grid>
26
+ <block type="core/text_list" name="root" output="toHtml">
27
+ <block type="connector/adminhtml_content_cmsPage_grid" name="admin.cmspage.grid"/>
28
+ </block>
29
+ </connector_adminhtml_translator_cmspage_grid>
30
+
31
+ <connector_adminhtml_translator_cmsblock_index>
32
+ <reference name="content">
33
+ <block type="connector/adminhtml_content_cmsBlock" name="cmsblock.grid" />
34
+ </reference>
35
+ </connector_adminhtml_translator_cmsblock_index>
36
+
37
+ <connector_adminhtml_translator_product_index>
38
+ <reference name="content">
39
+ <block type="connector/adminhtml_content_product" name="product.grid" />
40
+ </reference>
41
+ </connector_adminhtml_translator_product_index>
42
+
43
+ <connector_adminhtml_translator_category_index>
44
+ <reference name="content">
45
+ <block type="connector/adminhtml_content_category" name="category.grid" />
46
+ </reference>
47
+ </connector_adminhtml_translator_category_index>
48
+
49
+ <connector_adminhtml_translator_view>
50
+ <reference name="content">
51
+ <block type = "connector/adminhtml_content" name = "content.grid" />
52
+ </reference>
53
+ </connector_adminhtml_translator_view>
54
+
55
+ <connector_adminhtml_translator_logs>
56
+ <reference name="content">
57
+ <block type="connector/adminhtml_logs_view" name="actions.logs" />
58
+ </reference>
59
+ </connector_adminhtml_translator_logs>
60
+
61
+ <connector_adminhtml_translator_errors>
62
+ <update handle="connector_adminhtml_translator_logs" />
63
+ </connector_adminhtml_translator_errors>
64
+
65
+ <connector_adminhtml_instance_edit>
66
+ <reference name="head">
67
+ <action method="addJs">
68
+ <file>smartling/locales_bulk_validation.js</file>
69
+ </action>
70
+ <action method="addJs">
71
+ <file>smartling/select_all.js</file>
72
+ </action>
73
+ </reference>
74
+ <reference name="content">
75
+ <block type="connector/adminhtml_instance_edit" name="create.translations" />
76
+ </reference>
77
+ <reference name="left">
78
+ <block type="connector/adminhtml_instance_tabs" name="projects.edit.tabs" />
79
+ </reference>
80
+ </connector_adminhtml_instance_edit>
81
+
82
+ <adminhtml_cms_page_edit>
83
+ <reference name="head">
84
+ <action method="addJs"><file>smartling/select_all.js</file></action>
85
+ </reference>
86
+ <reference name = "cms_page_edit_tabs">
87
+ <block type="connector/adminhtml_cms_page_edit_tab_translations" name="cms_page_edit_tab_translations" />
88
+ <action method="addTab"><name>translation_section</name><block>connector/adminhtml_cms_page_edit_tab_translations</block></action>
89
+ </reference>
90
+ </adminhtml_cms_page_edit>
91
+
92
+ <adminhtml_cms_block_edit>
93
+ <reference name="head">
94
+ <action method="addJs"><file>smartling/select_all.js</file></action>
95
+ </reference>
96
+ </adminhtml_cms_block_edit>
97
+
98
+ <adminhtml_catalog_product_edit>
99
+ <reference name="head">
100
+ <action method="addJs"><file>smartling/select_all.js</file></action>
101
+ </reference>
102
+ <reference name="product_tabs">
103
+ <block type="connector/adminhtml_catalog_product_edit_tab_translations" name="catalog_product_edit_tab_translations" />
104
+ <action method="addTab"><name>translation_section</name><block>connector/adminhtml_catalog_product_edit_tab_translations</block></action>
105
+ </reference>
106
+ </adminhtml_catalog_product_edit>
107
+
108
+ <adminhtml_catalog_product_new>
109
+ <reference name="head">
110
+ <action method="addJs"><file>smartling/select_all.js</file></action>
111
+ </reference>
112
+ <reference name="product_tabs">
113
+ <block type="connector/adminhtml_catalog_product_edit_tab_translations" name="catalog_product_edit_tab_translations" />
114
+ <action method="addTab"><name>translation_section</name><block>connector/adminhtml_catalog_product_edit_tab_translations</block></action>
115
+ </reference>
116
+ </adminhtml_catalog_product_new>
117
+
118
+ <adminhtml_catalog_category_edit>
119
+ <reference name="head">
120
+ <action method="addJs"><file>smartling/select_all.js</file></action>
121
+ </reference>
122
+ <reference name="head">
123
+ <action method="addJs"><file>smartling/content.js</file></action>
124
+ </reference>
125
+ </adminhtml_catalog_category_edit>
126
+
127
+ <adminhtml_catalog_product_attribute_edit>
128
+ <reference name="head">
129
+ <action method="addJs"><file>smartling/select_all.js</file></action>
130
+ </reference>
131
+ <reference name="attribute_edit_tabs">
132
+ <block type="connector/adminhtml_catalog_product_attributes_edit_tab_translations" after="labels" name="tab_translations"/>
133
+ <action method="addTabAfter">
134
+ <name>translation_section</name>
135
+ <block>tab_translations</block>
136
+ <after>labels</after>
137
+ </action>
138
+ </reference>
139
+ </adminhtml_catalog_product_attribute_edit>
140
+
141
+ <connector_adminhtml_projects_new>
142
+ <reference name="left">
143
+ <block type="connector/adminhtml_projects_new_tabs" name="projects.edit.tabs" />
144
+ </reference>
145
+ <reference name="content">
146
+ <block type="connector/adminhtml_projects_new" name="projects" />
147
+ </reference>
148
+ </connector_adminhtml_projects_new>
149
+
150
+ <connector_adminhtml_projects_edit>
151
+ <reference name="head">
152
+ <action method="addJs">
153
+ <file>smartling/locales_validation.js</file>
154
+ </action>
155
+ </reference>
156
+ <reference name="left">
157
+ <block type="connector/adminhtml_projects_edit_tabs" name="projects.edit.tabs" />
158
+ </reference>
159
+ <reference name="content">
160
+ <block type="connector/adminhtml_projects_edit" name="projects" />
161
+ </reference>
162
+ </connector_adminhtml_projects_edit>
163
+
164
+ <connector_adminhtml_attributes_product>
165
+ <reference name="content">
166
+ <block type="connector/adminhtml_catalog_product_attributes" name="product_attributes"/>
167
+ <block type="core/template" template="connector/adminhtml/widget/grid/translate_status.phtml" name="translate_status">
168
+ <action method="setData">
169
+ <name>entity_type</name>
170
+ <value>product</value>
171
+ </action>
172
+ </block>
173
+ </reference>
174
+ </connector_adminhtml_attributes_product>
175
+
176
+ <connector_adminhtml_attributes_category>
177
+ <reference name="content">
178
+ <block type="connector/adminhtml_catalog_category_attributes" name="product_attributes" />
179
+ <block type="core/template" template="connector/adminhtml/widget/grid/translate_status.phtml" name="translate_status">
180
+ <action method="setData">
181
+ <name>entity_type</name>
182
+ <value>category</value>
183
+ </action>
184
+ </block>
185
+ </reference>
186
+ </connector_adminhtml_attributes_category>
187
+
188
+ <connector_adminhtml_fields_pages>
189
+ <reference name="content">
190
+ <block type="connector/adminhtml_cms_page_fields" name="page_fields" />
191
+ <block type="core/template" template="connector/adminhtml/widget/grid/translate_status.phtml" name="translate_status">
192
+ <action method="setData">
193
+ <name>entity_type</name>
194
+ <value>cmsPage</value>
195
+ </action>
196
+ </block>
197
+ </reference>
198
+ </connector_adminhtml_fields_pages>
199
+
200
+ <connector_adminhtml_fields_blocks>
201
+ <reference name="content">
202
+ <block type="connector/adminhtml_cms_block_fields" name="block_fields" />
203
+ <block type="core/template" template="connector/adminhtml/widget/grid/translate_status.phtml" name="translate_status">
204
+ <action method="setData">
205
+ <name>entity_type</name>
206
+ <value>cmsBlock</value>
207
+ </action>
208
+ </block>
209
+ </reference>
210
+ </connector_adminhtml_fields_blocks>
211
+
212
+ </layout>
app/design/adminhtml/default/default/template/connector/adminhtml/edit/tab/bulk_translations.phtml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $options = $this->getOptions();
3
+ $localesCounter = 0;
4
+ ?>
5
+ <table>
6
+ <tbody>
7
+ <?php foreach ($options as $projectId => $projectData) :?>
8
+ <tr>
9
+ <td colspan="3">
10
+ <b><?php echo $projectData['name'];?></b>
11
+ </td>
12
+ </tr>
13
+ <?php
14
+ if(sizeof($projectData['locales']))
15
+ foreach ($projectData['locales'] as $storeId => $locale):
16
+ $localesCounter++;
17
+ $element_id = 'locales_' . $this->getEntityType() . '_' . $projectId . '_' . $storeId;
18
+
19
+ ?>
20
+ <tr>
21
+ <td class="value" nowrap>
22
+ <input id="<?php echo $element_id;?>"
23
+ type="checkbox"
24
+ name="locales[<?php echo $projectId;?>][]"
25
+ value="<?php echo $storeId; ?>"
26
+ class="sl-required-entry-bulk locales"/>
27
+ <label for='<?php echo $element_id;?>' style="display:inline;">
28
+ <?php echo $locale['name'];?>
29
+ </label>
30
+ </td>
31
+ </tr>
32
+ <?php endforeach; ?>
33
+ <?php endforeach; ?>
34
+
35
+ </tbody>
36
+ <tfoot>
37
+ <?php
38
+ if($localesCounter>1):
39
+ ?>
40
+ <tr>
41
+ <td colspan="3">
42
+ <p>
43
+ <a href="javascript:void(0)" onclick="selectAll(this);">
44
+ <span><?php echo Mage::helper('connector')->__('Check All'); ?></span>
45
+ <span style="display:none"><?php echo Mage::helper('connector')->__('Uncheck All'); ?></span>
46
+ </a>
47
+ </p>
48
+ </td>
49
+ </tr>
50
+ <?php
51
+ else:
52
+ ?>
53
+ <tr>
54
+ <td colspan="3">&nbsp;</td>
55
+ </tr>
56
+ <?php
57
+ endif;
58
+ ?>
59
+ </tfoot>
60
+ </table>
app/design/adminhtml/default/default/template/connector/adminhtml/edit/tab/translations.phtml ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if(!$this->getContentId()):
4
+ echo Mage::helper('connector')->__('Please, select item');
5
+ else:
6
+
7
+ $projects = $this->findAvailableLocales($this->getContentTypeId(), $this->getContentId(), $this->getWebsites());
8
+ $contentItems = $this->getContentItems();
9
+ $contentType = $this->getContentTypeId();
10
+ $localesCounter = 0;
11
+ ?>
12
+ <?php if(sizeof($projects) > 0): ?>
13
+ <div id="result">
14
+ </div>
15
+ <h2><?php echo $this->getTitle() ;?></h2>
16
+ <h4><?php echo $this->__('Target stores and Locales'); ?></h4>
17
+ <table>
18
+ <tbody>
19
+ <?php foreach ($projects as $projectId => $projectData) :?>
20
+ <tr>
21
+ <td colspan="3">
22
+ <b><?php echo $projectData['name'];?></b>
23
+ </td>
24
+ </tr>
25
+ <?php
26
+ if(sizeof($projectData['locales']))
27
+ foreach ($projectData['locales'] as $storeId => $locale):
28
+ $localesCounter++;
29
+ $element_id = 'locales_' . $projectId . '_' . $storeId;
30
+ ?>
31
+ <tr>
32
+ <td <?php if(!is_null($locale['percent'])):?> colspan="3"<?php endif; ?> nowrap>
33
+ <input id="<?php echo $element_id;?>" class="locales"
34
+ type="checkbox" id="translations"
35
+ name="locales[<?php echo $projectId;?>][]"
36
+ value="<?php echo $storeId; ?>"
37
+ <?php if(!is_null($locale['percent'])) echo 'checked="checked"';?>
38
+ />
39
+ <label for='<?php echo $element_id;?>' style="display:inline;">
40
+ <?php echo $locale['name'];?>
41
+ </label>
42
+ </td>
43
+ <?
44
+ if(!is_null($locale['percent'])):
45
+ ?>
46
+ <td align="right">
47
+ <img src="<?php echo $this->getStatusImageUrl ($locale['percent'], true) ;?>" style="vertical-align: top;" />
48
+ </td>
49
+ <td width="30">
50
+ <span><?php echo $locale['percent'] . "%" ;?></span>
51
+ </td>
52
+ <? endif;?>
53
+ </tr>
54
+ <?php endforeach; ?>
55
+ <?php endforeach; ?>
56
+ </tbody>
57
+ <tfoot>
58
+ <?php
59
+ if($localesCounter>1):
60
+ ?>
61
+ <tr>
62
+ <td colspan="3">
63
+ <p>
64
+ <a href="javascript:void(0)" onclick="selectAll(this);">
65
+ <span><?php echo Mage::helper('connector')->__('Check All'); ?></span>
66
+ <span style="display:none"><?php echo Mage::helper('connector')->__('Uncheck All'); ?></span>
67
+ </a>
68
+ </p>
69
+ </td>
70
+ </tr>
71
+ <?php
72
+ else:
73
+ ?>
74
+ <tr><td colspan="3">&nbsp;</td></tr>
75
+ <?php
76
+ endif;
77
+ ?>
78
+ <?php if ($this->getContentId()): ?>
79
+ <tr>
80
+ <td>
81
+ <?php $label = $this->__('Send to Smartling') ;?>
82
+ <?php echo $this->getButtonHtmlContent('upload-content', $label);?>
83
+ </td>
84
+ <td colspan="2">
85
+ <?php echo $this->getButtonHtmlContent('download-content', $this->__('Download translation'));?>
86
+ </td>
87
+ </tr>
88
+ <?php endif; ?>
89
+ </tfoot>
90
+ </table>
91
+ <?php if ($this->getContentId()): ?>
92
+ <script type="text/javascript" src="<?php echo Mage::getBaseUrl('js') . 'smartling' . DS . 'content.js' ;?>">
93
+ </script>
94
+ <script type="text/javascript">
95
+ Event.observe('upload-content', 'click', function(event) {
96
+ <?php $data = array('content_id' => $this->getContentId(), 'content_type' => $contentType); ?>
97
+ var url = '<?php echo $this->getUrl('smartling/adminhtml_translator/uploadsingle', $data) ;?>';
98
+ var params = Form.serializeElements($$('input.locales'));
99
+ singleContentActions(url, params);
100
+ Event.stop(event);
101
+ });
102
+
103
+ Event.observe('download-content', 'click', function(event) {
104
+ <?php $data = array('content_id' => $this->getContentId(), 'content_type' => $contentType); ?>
105
+ var url = '<?php echo $this->getUrl('smartling/adminhtml_translator/downloadsingle', $data) ;?>';
106
+ var params = Form.serializeElements($$('input.locales'));
107
+ singleContentActions(url, params);
108
+ Event.stop(event);
109
+ });
110
+
111
+ </script>
112
+ <?php endif; ?>
113
+ <?php else:
114
+ echo Mage::helper('connector')->__('Sorry. No one profile for this item is available.');
115
+ ?>
116
+ <?php endif; ?>
117
+ <?php endif; ?>
app/design/adminhtml/default/default/template/connector/adminhtml/logs/view.phtml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * To change this template, choose Tools | Templates
5
+ * and open the template in the editor.
6
+ */
7
+
8
+ $content = $this->getLogContent();
9
+ ?>
10
+
11
+ <div>
12
+ <?php echo nl2br($content); ?>
13
+ </div>
app/design/adminhtml/default/default/template/connector/adminhtml/system/config/connectionbutton.phtml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $url = $this->getServiceUrl(); ?>
2
+ <script type = "text/javascript">
3
+
4
+ function testConnection(){
5
+ var apiKey = $('key').getValue();
6
+ var projectId = $('project_id').getValue();
7
+
8
+ new Ajax.Request('<?php echo $url; ?>', {
9
+ method: 'get',
10
+ parameters: {apiKey: apiKey, projectId: projectId},
11
+ onComplete: function(transport){
12
+ var response = transport.responseText.evalJSON(true);
13
+ showMessage(response);
14
+ }
15
+ });
16
+ }
17
+
18
+ function showMessage(response){
19
+ if (response.result == "SUCCESS"){
20
+ var className = "success-msg";
21
+ } else {
22
+ var className = "error-msg";
23
+ }
24
+ var message = "<ul><li><span>" + response.message + "</span></li></ul>"
25
+ var block = "<li id='api-message' class='" + className + "'>" + message + "</li>";
26
+ $('api-message').replace(block);
27
+ }
28
+
29
+ </script>
30
+ <?php echo $this->getButton() ;?>
31
+ <ul class="messages">
32
+ <li id="api-message"></li>
33
+ </ul>
app/design/adminhtml/default/default/template/connector/adminhtml/system/config/contentfields.phtml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $values = $this->getValues(); ?>
2
+ <input type="hidden" name="<?php echo $this->getNamePrefix() ;?>" value="" />
3
+ <div style="overflow-y: scroll; height: 200px;">
4
+ <ul class="checkboxes">
5
+ <?php foreach ($values as $_option) :?>
6
+ <li>
7
+ <input type="checkbox" name="<?php echo $this->getNamePrefix() ;?>[]" value="<?php echo $_option['value']; ?>"
8
+ <?php echo ($this->isChecked($_option['value'])) ? " checked='checked'" : ""; ?> />
9
+ <label for="<?php echo $this->getHtmlId() . '_' . $_option['value'] ?>"><?php echo $_option['label'] ;?></label>
10
+ </li>
11
+ <?php endforeach;?>
12
+
13
+ </ul>
14
+ </div>
app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/massaction.phtml ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package default_default
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <div id="<?php echo $this->getHtmlId() ?>">
28
+ <table cellspacing="0" cellpadding="0" class="massaction">
29
+ <tr>
30
+ <td><?php if ($this->getUseSelectAll()):?>
31
+ <a href="#" onclick="return <?php echo $this->getJsObjectName() ?>.selectAll()"><?php echo $this->__('Select All') ?></a>
32
+ <span class="separator">|</span>
33
+ <a href="#" onclick="return <?php echo $this->getJsObjectName() ?>.unselectAll()"><?php echo $this->__('Unselect All') ?></a>
34
+ <span class="separator">|</span>
35
+ <?php endif; ?>
36
+ <a href="#" onclick="return <?php echo $this->getJsObjectName() ?>.selectVisible()"><?php echo $this->__('Select Visible') ?></a>
37
+ <span class="separator">|</span>
38
+ <a href="#" onclick="return <?php echo $this->getJsObjectName() ?>.unselectVisible()"><?php echo $this->__('Unselect Visible') ?></a>
39
+ <span class="separator">|</span>
40
+ <strong id="<?php echo $this->getHtmlId() ?>-count">0</strong> <?php echo $this->__('items selected') ?>
41
+ </td>
42
+ <td>
43
+ <div class="right">
44
+ <div class="entry-edit">
45
+ <?php if ($this->getHideFormElement() !== true):?>
46
+ <form action="<?php echo $this->getAction() ;?>" id="<?php echo $this->getHtmlId() ?>-form" method="post">
47
+ <?php endif ?>
48
+ <?php echo $this->getBlockHtml('formkey')?>
49
+ <fieldset>
50
+ <span class="field-row" style="display:none;">
51
+ <label><?php echo $this->__('Actions') ?></label>
52
+ <select id="<?php echo $this->getHtmlId() ?>-select" class="required-entry select absolute-advice local-validation">
53
+ <option value=""></option>
54
+ <?php foreach($this->getItems() as $_item): ?>
55
+ <option value="<?php echo $_item->getId() ?>"<?php echo ($_item->getSelected() ? ' selected="selected"' : '')?>><?php echo $_item->getLabel() ?></option>
56
+ <?php endforeach; ?>
57
+ </select>
58
+ </span>
59
+ <span class="outer-span" id="<?php echo $this->getHtmlId() ?>-form-hiddens"></span>
60
+ <span class="outer-span" id="<?php echo $this->getHtmlId() ?>-form-additional"></span>
61
+ <span class="field-row">
62
+ <?php echo $this->getApplyButtonHtml() ?>
63
+ </span>
64
+ </fieldset>
65
+ <?php if ($this->getHideFormElement() !== true):?>
66
+ </form>
67
+ <?php endif ?>
68
+ </div>
69
+
70
+ <div class="no-display">
71
+ <?php foreach($this->getItems() as $_item): ?>
72
+ <div id="<?php echo $this->getHtmlId() ?>-item-<?php echo $_item->getId() ?>-block">
73
+ <?php echo $_item->getAdditionalActionBlockHtml() ?>
74
+ </div>
75
+ <?php endforeach; ?>
76
+ </div>
77
+ </div>
78
+ </td>
79
+ </tr>
80
+ </table>
81
+ <?php if(!$this->getParentBlock()->canDisplayContainer()): ?>
82
+ <script type="text/javascript">
83
+ <?php echo $this->getJsObjectName() ?>.setGridIds('<?php echo $this->getGridIdsJson() ?>');
84
+ </script>
85
+ <?php endif; ?>
86
+ </div>
app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/scripts_wraper.phtml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <script>
2
+ varienGrid.prototype.initGrid = varienGrid.prototype.initGrid.wrap(function(parentMethod){
3
+ parentMethod.call(this);
4
+ new CheckStatuses();
5
+ });
6
+ </script>
7
+
app/design/adminhtml/default/default/template/connector/adminhtml/widget/grid/translate_status.phtml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ function translateStatus(obj, attribute) {
3
+ var changeStatusUrl = '<?php echo $this->getUrl('*/*/changeStatus');?>';
4
+
5
+ new Ajax.Request(changeStatusUrl, {
6
+ method: 'post',
7
+ parameters: {type: '<?php echo $this->getData('entity_type');?>', id: obj.value}
8
+ });
9
+ }
10
+ </script>
11
+
app/etc/modules/Smartling_Connector.xml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Smartling_Connector>
6
+ <active>true</active>
7
+ <codePool>community</codePool>
8
+ </Smartling_Connector>
9
+ </modules>
10
+ </config>
js/smartling/check_statuses.js ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var CheckStatuses = Class.create();
2
+
3
+ CheckStatuses.prototype = {
4
+
5
+ initialize: function() {
6
+ var nested = this;
7
+ setTimeout(function(){
8
+ nested.links = [];
9
+ nested.pushLinks();
10
+ nested.runRequest();
11
+ },50);
12
+ },
13
+
14
+ pushLinks: function() {
15
+
16
+ var downloadLinks = $$('a.download');
17
+ for(i = 0; i < downloadLinks.length; i++) {
18
+
19
+ link = downloadLinks[i].href.replace('/download/','/checkstatus/');
20
+ var contentId = link.match(/content_id\/(\d+)\//i);
21
+
22
+ var obj = new Object();
23
+ obj.id = contentId[1];
24
+ obj.link = link;
25
+
26
+ this.links.push(obj);
27
+ }
28
+
29
+
30
+ },
31
+
32
+ runRequest: function() {
33
+
34
+ for(i = 0; i < this.links.length; i++) {
35
+
36
+ new Ajax.Request(this.links[i].link,
37
+ {
38
+ method: 'POST',
39
+ parameters: {},
40
+ evalScripts: true,
41
+ loaderArea: false,
42
+ onSuccess: function(transport) {
43
+ try {
44
+
45
+ if (transport.responseText.isJSON()) {
46
+ var response = transport.responseText.evalJSON();
47
+
48
+ if(response.error == 1) {
49
+ this.logFail(response.message);
50
+ } else {
51
+ this.setPercent(response.element_id, response.percent);
52
+ }
53
+ this.stopLoader(response.element_id);
54
+
55
+ } else {
56
+ this.logFail('Smartling check status: Received format is not JSON.');
57
+ }
58
+ } catch (e) {
59
+ this.logFail(e);
60
+ }
61
+ }.bind(this)
62
+ }
63
+ );
64
+
65
+ }
66
+
67
+ },
68
+
69
+ logFail: function(message) {
70
+ if (window.console) {
71
+ window.console.log(message);
72
+ }
73
+ },
74
+
75
+ stopLoader: function(element_id) {
76
+ $('status_wraper_' + element_id).removeClassName('bar-loading');
77
+ },
78
+
79
+ setPercent: function(element_id, percent) {
80
+ if(this.is_numeric(element_id) && this.is_numeric(percent)) {
81
+ $('percent_' + element_id).setStyle({ display: "block", width: percent + '%'});
82
+ $('percent_content_' + element_id).update(percent + '%');
83
+ }
84
+ },
85
+
86
+ is_numeric: function( mixed_var ) {
87
+ return ( mixed_var == '' ) ? false : !isNaN( mixed_var );
88
+ }
89
+ }
90
+
js/smartling/content.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function singleContentActions(url, params) {
2
+ new Ajax.Request(url, {
3
+ method: 'post',
4
+ parameters: params,
5
+ onComplete: function(transport){
6
+ var response = transport.responseText.evalJSON(true);
7
+ showMessage(response);
8
+ }
9
+ });
10
+ }
11
+
12
+ function showMessage(response){
13
+ var block = "<div id='result'>" + response.messageblock + "</div>";
14
+ $('result').replace(block);
15
+ }
16
+
17
+
js/smartling/locales_bulk_validation.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Validation.add('sl-required-entry-bulk', 'One of checkboxes should be choosen', function(v) {
2
+
3
+ var checkedList = [];
4
+ $$('.sl-required-entry-bulk').each(function(ele) {
5
+
6
+ if ($(ele).checked)
7
+ {
8
+ checkedList.push($(ele).name);
9
+ }
10
+ });
11
+
12
+ return (checkedList.length > 0);
13
+ });
js/smartling/locales_validation.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Validation.add('sl-required-entry-multy', 'One of checkboxes should be choosen and appropriates locale is entered', function(v) {
2
+
3
+ var checkedList = [];
4
+ $$('.sl-required-entry-multy').each(function(ele) {
5
+
6
+ if ($(ele).checked && $(ele).next('input[type=text]').getValue().length > 0)
7
+ {
8
+ checkedList.push($(ele).name);
9
+ }
10
+ });
11
+
12
+ return (checkedList.length > 0);
13
+ });
js/smartling/select_all.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function selectAll(obj) {
3
+
4
+ var form = $(obj).up('form');
5
+
6
+ var status = $(obj).childElements()[0].visible();
7
+
8
+ var i=form.getElements('checkbox');
9
+ i.each(function(item)
10
+ {
11
+ item.checked = status;
12
+ }
13
+ );
14
+
15
+ $(obj).childElements().each(function(node){
16
+ $(node).toggle();
17
+ });
18
+
19
+ }
20
+
lib/SmartlingApi/lib/HttpClient.php ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Description of HttpClient
5
+ *
6
+ * @author Igor
7
+ */
8
+ class HttpClient {
9
+
10
+ const REQUEST_TYPE_GET = 'GET';
11
+ const REQUEST_TYPE_POST = 'POST';
12
+ const REQUEST_TYPE_PUT = 'PUT';
13
+ const REQUEST_TYPE_DELETE = 'DELETE';
14
+
15
+ protected $_uri;
16
+
17
+
18
+ /**
19
+ * http method
20
+ *
21
+ * @var string
22
+ */
23
+ protected $_method;
24
+
25
+ /**
26
+ *
27
+ * @var string
28
+ */
29
+ protected $_accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
30
+
31
+ /**
32
+ * flag for upload file
33
+ *
34
+ * @var bool
35
+ */
36
+ protected $_needUploadFile = false;
37
+
38
+ /**
39
+ * flag for update content
40
+ *
41
+ * @var bool
42
+ */
43
+ protected $_needUploadContent = false;
44
+
45
+ /**
46
+ * holds key in parameters for defining which param stores uploading data
47
+ *
48
+ * @var string
49
+ */
50
+ protected $_fileKey = 'file';
51
+
52
+ /**
53
+ *
54
+ * @var string
55
+ */
56
+ protected $_status;
57
+
58
+ /**
59
+ *
60
+ * @var array
61
+ */
62
+ protected $_headers = array();
63
+
64
+ /**
65
+ * stores response content
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_content = '';
70
+
71
+ /**
72
+ *
73
+ * @var array
74
+ */
75
+ protected $_errormsg;
76
+
77
+ /**
78
+ *
79
+ * @param string $uri
80
+ * @param int $port
81
+ */
82
+ public function __construct($uri, $port = 80) {
83
+ $this->_uri = $uri;
84
+ $this->setMethod(self::REQUEST_TYPE_GET);
85
+ }
86
+
87
+ /**
88
+ *
89
+ * @param string $method
90
+ * @return \HttpClient
91
+ */
92
+ public function setMethod($method){
93
+ $this->_method = $method;
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @return string
100
+ */
101
+ public function getStatus(){
102
+ return $this->_headers['http_code'];
103
+ }
104
+
105
+ /**
106
+ * @param resource $ch
107
+ * curl resource
108
+ * @param int $maxredirect
109
+ * maximum number of redirects that can be made in order to retrieve url content
110
+ *
111
+ * @return string
112
+ */
113
+ protected function curl_exec_follow($ch, &$maxredirect = null) {
114
+
115
+ // we emulate a browser here since some websites detect
116
+ // us as a bot and don't let us do our job
117
+ $user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5)".
118
+ " Gecko/20041107 Firefox/1.0";
119
+ curl_setopt($ch, CURLOPT_USERAGENT, $user_agent );
120
+
121
+ $mr = $maxredirect === null ? 5 : intval($maxredirect);
122
+
123
+ if (ini_get('open_basedir') == '' && ini_get('safe_mode') == 'Off') {
124
+
125
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
126
+ curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
127
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
128
+
129
+ } else {
130
+
131
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
132
+
133
+ if ($mr > 0)
134
+ {
135
+ $original_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
136
+ $newurl = $original_url;
137
+
138
+ $rch = curl_copy_handle($ch);
139
+
140
+ curl_setopt($rch, CURLOPT_HEADER, true);
141
+ curl_setopt($rch, CURLOPT_NOBODY, true);
142
+ curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
143
+ do
144
+ {
145
+ curl_setopt($rch, CURLOPT_URL, $newurl);
146
+ $header = curl_exec($rch);
147
+ if (curl_errno($rch)) {
148
+ $code = 0;
149
+ } else {
150
+ $code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
151
+ if ($code == 301 || $code == 302) {
152
+ preg_match('/Location:(.*?)\n/', $header, $matches);
153
+ $newurl = trim(array_pop($matches));
154
+
155
+ // if no scheme is present then the new url is a
156
+ // relative path and thus needs some extra care
157
+ if(!preg_match("/^https?:/i", $newurl)){
158
+ $newurl = $original_url . $newurl;
159
+ }
160
+ } else {
161
+ $code = 0;
162
+ }
163
+ }
164
+ } while ($code && --$mr);
165
+
166
+ curl_close($rch);
167
+
168
+ if (!$mr)
169
+ {
170
+ if ($maxredirect === null)
171
+ trigger_error('Too many redirects.', E_USER_WARNING);
172
+ else
173
+ $maxredirect = 0;
174
+
175
+ return false;
176
+ }
177
+ curl_setopt($ch, CURLOPT_URL, $newurl);
178
+ }
179
+ }
180
+ return curl_exec($ch);
181
+ }
182
+
183
+ /**
184
+ * make request
185
+ *
186
+ * @return array
187
+ */
188
+ protected function prepareFileFromString($data) {
189
+ // form field separator
190
+ $delimiter = '-------------' . uniqid();
191
+ // file upload fields: name => array(type=>'mime/type',content=>'raw data')
192
+ $fileFields = array(
193
+ 'file' => array(
194
+ 'type' => $data['fileType'],
195
+ 'content' => $data[$this->_fileKey],
196
+ ),
197
+ );
198
+ // all other fields (not file upload): name => value
199
+ $postFields = $data;
200
+ unset($postFields[$this->_fileKey]);
201
+
202
+ $post_data = '';
203
+ // populate normal fields first (simpler)
204
+ foreach ($postFields as $name => $content) {
205
+ $post_data .= "--" . $delimiter . "\r\n";
206
+ $post_data .= 'Content-Disposition: form-data; name="' . $name . '"';
207
+ // note: double endline
208
+ $post_data .= "\r\n\r\n";
209
+ $post_data .= $content . "\r\n";
210
+ }
211
+ // populate file fields
212
+ foreach ($fileFields as $name => $file) {
213
+ $post_data .= "--" . $delimiter . "\r\n";
214
+ // "filename" attribute is not essential; server-side scripts may use it
215
+ $post_data .= 'Content-Disposition: form-data; name="' . $name . '";' .
216
+ ' filename="' . $name . '"' . "\r\n";
217
+ // this is, again, informative only; good practice to include though
218
+ $post_data .= 'Content-Type: ' . $file['type'] . "\r\n";
219
+ // this endline must be here to indicate end of headers
220
+ $post_data .= "\r\n";
221
+ // the file itself (note: there's no encoding of any kind)
222
+ $post_data .= $file['content'] . "\r\n";
223
+ }
224
+ // last delimiter
225
+ $post_data .= "--" . $delimiter . "--\r\n";
226
+
227
+ return array('delimiter' => $delimiter, 'data' => $post_data);
228
+ }
229
+
230
+ /**
231
+ * make request
232
+ *
233
+ * @return string
234
+ */
235
+ public function request($data){
236
+ $get_params = '';
237
+ if ($this->_method == self::REQUEST_TYPE_GET || $this->_method == self::REQUEST_TYPE_DELETE) {
238
+ $get_params = '?' . http_build_query($data, NULL, '&');
239
+ }
240
+
241
+ $ch = curl_init();
242
+ curl_setopt($ch, CURLOPT_URL, $this->_uri . $get_params);
243
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
244
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
245
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
246
+
247
+ if (in_array($this->_method, array(self::REQUEST_TYPE_POST, self::REQUEST_TYPE_DELETE, self::REQUEST_TYPE_PUT))) {
248
+
249
+ if ($this->_needUploadFile || $this->_needUploadContent){
250
+ if ($this->_needUploadFile && file_exists(realpath($data[$this->_fileKey]))){
251
+ if ($this->_needUploadFile && file_exists(realpath($data[$this->_fileKey]))){
252
+ if (!class_exists('CURLFile')) {
253
+ $data['file'] = '@' . realpath($data['file']);
254
+ }
255
+ else {
256
+ $data['file'] = new CURLFile(realpath($data['file']));
257
+ }
258
+ }
259
+ }
260
+
261
+ if ($this->_needUploadContent && ($data[$this->_fileKey] !== '')){
262
+ $tmp = $this->prepareFileFromString($data);
263
+ $data = $tmp['data'];
264
+ $delimiter = $tmp['delimiter'];
265
+
266
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
267
+ 'Content-Type: multipart/form-data; boundary=' . $delimiter,
268
+ 'Content-Length: ' . strlen($data)));
269
+ }
270
+ }
271
+
272
+ curl_setopt($ch, CURLOPT_POST, 1);
273
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
274
+ }
275
+
276
+ $result = $this->_content = $this->curl_exec_follow($ch);// curl_exec($ch);
277
+ $this->_headers = curl_getinfo($ch);
278
+
279
+ if (!$result) {
280
+ $this->_errormsg = 'Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch);
281
+ }
282
+ curl_close($ch);
283
+
284
+ return $result;
285
+ }
286
+
287
+ /**
288
+ *
289
+ * @return string
290
+ */
291
+ public function getContent(){
292
+ return $this->_content;
293
+ }
294
+
295
+ /**
296
+ * set flag for uploading file content
297
+ *
298
+ * @param bool $flag Description
299
+ * @return HttpClient
300
+ */
301
+ public function setNeedUploadFile($flag){
302
+ $this->_needUploadFile = $flag;
303
+ return $this;
304
+ }
305
+
306
+ /**
307
+ * set flag for uploading content
308
+ *
309
+ * @param bool $flag
310
+ * @return \HttpClient
311
+ */
312
+ public function setNeedUploadContent($flag){
313
+ $this->_needUploadContent = $flag;
314
+ return $this;
315
+ }
316
+
317
+ public function getError() {
318
+ return $this->_errormsg;
319
+ }
320
+ }
lib/SmartlingApi/lib/SmartlingAPI.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once("HttpClient.php");
4
+ require_once("FileUploadParameterBuilder.php");
5
+
6
+ class SmartlingAPI {
7
+
8
+ const SANDBOX_MODE = 'SANDBOX';
9
+ const PRODUCTION_MODE = 'PRODUCTION';
10
+ const SANDBOX_URL = 'https://sandbox-api.smartling.com/v1';
11
+ const PRODUCTION_URL = 'https://api.smartling.com/v1';
12
+
13
+ /**
14
+ * api base url
15
+ *
16
+ * @var string
17
+ */
18
+ protected $_baseUrl = "";
19
+
20
+ /**
21
+ *
22
+ * @var string
23
+ */
24
+ protected $_apiKey;
25
+
26
+ /**
27
+ *
28
+ * @var string
29
+ */
30
+ protected $_projectId;
31
+
32
+ /**
33
+ *
34
+ * @var null | string
35
+ */
36
+ protected $_response = null;
37
+
38
+ public function __construct($baseUrl, $apiKey, $projectId, $mode = self::SANDBOX_MODE) {
39
+ $this->_apiKey = $apiKey;
40
+ $this->_projectId = $projectId;
41
+ if ($mode == self::PRODUCTION_MODE) {
42
+ if (!empty($baseUrl)) {
43
+ $this->_baseUrl = $baseUrl;
44
+ }
45
+ else {
46
+ $this->_baseUrl = self::PRODUCTION_URL;
47
+ }
48
+ }
49
+ else {
50
+ $this->_baseUrl = self::SANDBOX_URL;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * upload file to Smartling service
56
+ *
57
+ * @param string $path
58
+ * @param array $params
59
+ * @return string
60
+ */
61
+ public function uploadFile($path, $params = array()) {
62
+ $params['file'] = $path;
63
+ return $this->sendRequest('file/upload', $params, HttpClient::REQUEST_TYPE_POST, true);
64
+ }
65
+
66
+ /**
67
+ * upload content to Smartling service
68
+ *
69
+ * @param string $content
70
+ * @param array $params
71
+ * @return string
72
+ */
73
+ public function uploadContent($content, $params = array()) {
74
+ $params['file'] = $content;
75
+ return $this->sendRequest('file/upload', $params, HttpClient::REQUEST_TYPE_POST, false, true);
76
+ }
77
+
78
+ /**
79
+ * download translated content from Smartling Service
80
+ *
81
+ * @param string $fileUri
82
+ * @param string $locale
83
+ * @return string
84
+ */
85
+ public function downloadFile($fileUri, $locale, $params = array()) {
86
+ return $this->sendRequest('file/get', array_replace_recursive(array(
87
+ 'fileUri' => $fileUri,
88
+ 'locale' => $locale
89
+ ), $params), HttpClient::REQUEST_TYPE_GET);
90
+ }
91
+
92
+ /**
93
+ * retrieve status about file translation progress
94
+ *
95
+ * @param string $fileUri
96
+ * @param string $locale
97
+ * @return string
98
+ */
99
+ public function getStatus($fileUri, $locale, $params = array()) {
100
+ return $this->sendRequest('file/status', array_replace_recursive(array(
101
+ 'fileUri' => $fileUri,
102
+ 'locale' => $locale
103
+ ), $params), HttpClient::REQUEST_TYPE_GET);
104
+ }
105
+
106
+ /**
107
+ * get uploaded files list
108
+ *
109
+ * @param string $locale
110
+ * @param array $params
111
+ * @return string
112
+ */
113
+ public function getList($locale = '', $params = array()) {
114
+ $params = (empty($locale)) ? $params : array_replace_recursive(array('locale' => $locale), $params);
115
+ return $this->sendRequest('file/list', $params, HttpClient::REQUEST_TYPE_GET);
116
+ }
117
+
118
+ /**
119
+ * rename uploaded before files
120
+ *
121
+ * @param string $fileUri
122
+ * @param string $newFileUri
123
+ * @return string
124
+ */
125
+ public function renameFile($fileUri, $newFileUri) {
126
+ return $this->sendRequest('file/rename', array(
127
+ 'fileUri' => $fileUri,
128
+ 'newFileUri' => $newFileUri,
129
+ ), HttpClient::REQUEST_TYPE_POST);
130
+ }
131
+
132
+ /**
133
+ * remove uploaded files from Smartling Service
134
+ *
135
+ * @param string $fileUri
136
+ * @return string
137
+ */
138
+ public function deleteFile($fileUri) {
139
+ return $this->sendRequest('file/delete', array(
140
+ 'fileUri' => $fileUri,
141
+ ), HttpClient::REQUEST_TYPE_DELETE);
142
+ }
143
+
144
+ /**
145
+ * get locale list for project
146
+ *
147
+ * @return string
148
+ */
149
+ public function getLocaleList() {
150
+ return $this->sendRequest('project/locale/list', array(), HttpClient::REQUEST_TYPE_GET);
151
+ }
152
+
153
+ /**
154
+ * import files form Service
155
+ *
156
+ * @param string $fileUri
157
+ * @param string $fileType
158
+ * @param string $locale
159
+ * @param string $file
160
+ * @param string $overwrite
161
+ * @param string $translationState
162
+ * @return string
163
+ */
164
+ public function import($fileUri, $fileType, $locale, $file, $overwrite = false, $translationState) {
165
+
166
+ return $this->sendRequest('file/import', array(
167
+ 'fileUri' => $fileUri,
168
+ 'fileType' => $fileType,
169
+ 'locale' => $locale,
170
+ 'file' => $file,
171
+ 'overwrite' => $overwrite,
172
+ 'translationState' => $translationState,
173
+ ), HttpClient::REQUEST_TYPE_POST, true);
174
+ }
175
+
176
+ /**
177
+ * send request to Smartling Service
178
+ *
179
+ * @param string $uri
180
+ * @param array $requestData
181
+ * @param string $method
182
+ * @return string
183
+ */
184
+ protected function sendRequest($uri, $requestData, $method, $needUploadFile = false, $needUploadContent = false) {
185
+ $connection = new HttpClient($this->_baseUrl . "/" . $uri, 443);
186
+
187
+ $data['apiKey'] = $this->_apiKey;
188
+ $data['projectId'] = $this->_projectId;
189
+
190
+ $request = array_replace_recursive($data, $requestData);
191
+
192
+ $connection->setMethod($method)
193
+ ->setNeedUploadFile($needUploadFile)
194
+ ->setNeedUploadContent($needUploadContent);
195
+
196
+
197
+ if ($res = $connection->request($request)) {
198
+ return $this->_response = $connection->getContent();
199
+ }
200
+ else {
201
+ return new Exception("Can't connect to server");
202
+ }
203
+ }
204
+
205
+ /**
206
+ *
207
+ * @return boolean | string
208
+ */
209
+ public function getCodeStatus() {
210
+ if (!is_null($this->_response)) {
211
+ if ($result = json_decode($this->_response)) {
212
+ return $result->response->code;
213
+ }
214
+ }
215
+ else {
216
+ return false;
217
+ }
218
+ }
219
+
220
+ }
package.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>smartling</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.smartling.com/translation-software/integrations/">Custom</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Smartling-Magento integration package</summary>
10
+ <description>This package allows you:&#xD;
11
+ &#xD;
12
+ Upload for translation:&#xD;
13
+ Products, categories, attributes&#xD;
14
+ CMS pages and static block&#xD;
15
+ Localization files&#xD;
16
+ Dowload translated content:&#xD;
17
+ From product entity page&#xD;
18
+ From CMS entity page&#xD;
19
+ From Submissions board&#xD;
20
+ Set-up of Smartling configuration&#xD;
21
+ </description>
22
+ <notes>Stable version</notes>
23
+ <authors><author><name>Dmitriy Studinskiy</name><user>dstudinskiy</user><email>dms@smartling.com</email></author></authors>
24
+ <date>2015-04-03</date>
25
+ <time>15:43:15</time>
26
+ <contents><target name="magelib"><dir name="SmartlingApi"><dir name="lib"><file name="HttpClient.php" hash="1d13c92a6a47641f1740002f1cafb254"/><file name="SmartlingAPI.php" hash="8140f224a3c70dcb74142e0493e7fe6a"/></dir></dir></target><target name="magecommunity"><dir name="Smartling"><dir name="Connector"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><file name="AbstractEavGrid.php" hash="25712b617b597c595f63b56261e2f664"/><dir name="Category"><dir name="Attributes"><file name="Grid.php" hash="11e5d20bf6edd2bec56805329b0d63dc"/></dir><file name="Attributes.php" hash="2d5e1071b6f4433d35adbcb4a0348649"/><dir name="Tab"><file name="Observer.php" hash="a09f87d6bcdd499d751f566166793de2"/><file name="TranslateExisting.php" hash="f9025b1690d471ca683383a5f486c578"/><file name="Translations.php" hash="27b771119e620ab6bd805d49f4defd7d"/></dir></dir><dir name="Product"><dir name="Attributes"><dir name="Edit"><dir name="Tab"><file name="Translations.php" hash="2c08e2e2f6ce499489282c6579fabc0d"/></dir></dir><file name="Grid.php" hash="ff1d6795beab68e16e56e8d92ccbf43a"/></dir><file name="Attributes.php" hash="5781be69d7cb12145f5f20553da57203"/><dir name="Edit"><dir name="Tab"><file name="Translations.php" hash="9ecebc86b1872de5778fe5ab9e430bcd"/></dir></dir></dir></dir><dir name="Cms"><file name="AbstractFlatGrid.php" hash="0794e804d3d0dea174569b2f46731e43"/><dir name="Block"><dir name="Edit"><file name="Form.php" hash="f91888503dcdf0f71461c120e26fde52"/><dir name="Translations"><file name="Fieldset.php" hash="66bfdca871a7a7f72b8b622f0458a86b"/></dir><file name="Translations.php" hash="9eb586c9da981df782424166efe6fc2d"/></dir><dir name="Fields"><file name="Grid.php" hash="1bf108129865a437332981c388399c92"/></dir><file name="Fields.php" hash="403438843e48defdfe1176e350bfe5ba"/></dir><dir name="Page"><dir name="Edit"><dir name="Tab"><file name="Translations.php" hash="62f3c4b8c29f2cee893c51e1709ef8b0"/></dir></dir><dir name="Fields"><file name="Grid.php" hash="42db80d3128c5bb05ccc6a7bebdb93f4"/></dir><file name="Fields.php" hash="ab122ee2f71039aa44054593048dd5f7"/></dir></dir><dir name="Content"><dir name="Attribute"><file name="Grid.php" hash="0bc37a0fec4a5f2a174c73ed5961228f"/></dir><file name="Attribute.php" hash="994006c270b39d508e7cd8c56923ae1c"/><dir name="Category"><file name="Grid.php" hash="38329d6d42f43d1a5bb80deaf3139c2d"/></dir><file name="Category.php" hash="ecf5dcae6b6ee1e39d0241ff74059240"/><dir name="CmsBlock"><file name="Grid.php" hash="cafe11fc337a5e6c94c213cf8429a957"/></dir><file name="CmsBlock.php" hash="c1e0b485c384c6b9dc0d1089685a5327"/><dir name="CmsPage"><file name="Grid.php" hash="e721d81f1b64fcfcbd5ba0dd60384c00"/></dir><file name="CmsPage.php" hash="d49cca417c0b43162b37f2f9a23ca448"/><dir name="Grid"><dir name="Column"><file name="Status.php" hash="ff2f39d506c65a08afa7dc46c18577bd"/></dir></dir><file name="Grid.php" hash="574d1df9c5befd5689ff99ae9a29f877"/><dir name="Localization"><file name="Grid.php" hash="928fb1dd778becfcf20486b62fc39131"/></dir><file name="Localization.php" hash="8b61cf9c24c32d998ac72596f56c1845"/><dir name="Product"><file name="Grid.php" hash="2c51e6f17197f22e6930abb54d487576"/></dir><file name="Product.php" hash="5ad76c2541f28d131d2e0266837c216f"/></dir><file name="Content.php" hash="066d8c57e5d757ee9c9a24906f1b353c"/><dir name="Edit"><dir name="Tab"><file name="Translations.php" hash="3ecbad66914aa859c797c805e825a10d"/></dir></dir><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Download.php" hash="01a685d88260d85887818d594594ea8f"/><file name="Link.php" hash="8e36afa46b6ebd7dd8e841bbc1db9e3a"/><file name="Progress.php" hash="d058d4c6d3eca12e58dfef180f045338"/></dir></dir><file name="Massaction.php" hash="e485e6ffe10ad2bd01f1eab8dc281028"/></dir><dir name="Instance"><dir name="Edit"><file name="Form.php" hash="f7b44a15acac3cf8d4ccccf4c0ab589a"/></dir><file name="Edit.php" hash="eea9c7dbae4b92255bece5d9418d4426"/><dir name="Tab"><file name="Attribute.php" hash="9f50e0c568ad8fb24a0a6fe33e672504"/><file name="Category.php" hash="dc7f281394dc5209345564261423be0a"/><file name="CmsBlock.php" hash="8b2cb10506850150d400724428682d5c"/><file name="CmsPage.php" hash="e8e2c474db5ed0fc7796a8b49e0a4ad3"/><file name="Default.php" hash="f3dd8c98da77bb89eff0554acddf6924"/><file name="Localization.php" hash="7980ce5722b638b462ae66738451a328"/><file name="Product.php" hash="3a821e078e99f80c1996f80710c9a85d"/></dir><file name="Tabs.php" hash="fe08b031d213218c5b9b62f84239a2f0"/><file name="Widget.php" hash="f3eae37ea71f8370c3fa23f0f39cbef6"/></dir><dir name="Localization"><dir name="Files"><dir name="Edit"><file name="Form.php" hash="d9652815fd3312bbb7aab43a9446e34e"/></dir></dir></dir><dir name="Logs"><dir name="View"><file name="Grid.php" hash="89d5b2fe09a1d329ede2c689bc4a7f57"/></dir><file name="View.php" hash="e450b44564527d22f1f14407abf98b49"/></dir><dir name="Projects"><dir name="Edit"><dir name="Form"><dir name="Element"><file name="Profiles.php" hash="9ae276fdee0be096905bf3605f1179e7"/><file name="StoreViewLabel.php" hash="c005cf5be248fab99e973fb163645e84"/></dir></dir><file name="Form.php" hash="d32a527c7cc993d6bd683b382702294d"/><dir name="Tabs"><file name="Form.php" hash="ff71b169392d9e7ba420b754b9ede75b"/></dir><file name="Tabs.php" hash="10e0bc3fe1f390e01dc4af04c93864e0"/></dir><file name="Edit.php" hash="bfba4c72be1ddf9747c49756c1120640"/><file name="Grid.php" hash="97ba7c957a5946fac0c325251eea4316"/><dir name="Locales"><file name="Form.php" hash="e5349b3906937950c96982954b7f2bd7"/></dir><dir name="New"><dir name="Form"><dir name="Element"><file name="StoreViewLabel.php" hash="c005cf5be248fab99e973fb163645e84"/></dir></dir><file name="Form.php" hash="da4cf6182a46679f50c5050bd0b24302"/><dir name="Tabs"><file name="Form.php" hash="6916f411fae25a2794af6fe317805dea"/></dir><file name="Tabs.php" hash="f0c3dd9ae3654735018a6201a56a8f2c"/></dir><file name="New.php" hash="d779b3393ca87a9dbf28aae2d9dbe988"/></dir><file name="Projects.php" hash="c4ec56bf9b78325da901bf7fc17317f5"/><dir name="System"><dir name="Config"><file name="ConnectionButton.php" hash="3602f6d0d9d99fbfbafc6a96ff8b322a"/><file name="ContentFields.php" hash="4986c18474800b03b707c7e0f5ca9814"/><file name="Version.php" hash="4649c4bb21648ccf57d5dfbcd132e673"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="c2ddbb109157a4cf341a56fdbd87cf9b"/></dir><dir name="Model"><dir name="Content"><file name="Abstract.php" hash="0cc53f7a7d5bf6f55228cfb71867b0d4"/><file name="Attribute.php" hash="702b7d24eeec5efee0fec7fdf070ecc3"/><dir name="Attributes"><file name="Builder.php" hash="489e34681ddd53a7649aea708294857f"/><file name="Options.php" hash="6812b0e44ac07412edb43b75b7837b10"/></dir><dir name="Category"><file name="Observer.php" hash="af48570ce37c86ee2b9e20c91db2be5c"/></dir><file name="Category.php" hash="10ca2e808a99cc8ff50e77b3ee842328"/><dir name="CmsBlock"><file name="Observer.php" hash="d0c416a0976b8d96fc14d06858292c46"/></dir><file name="CmsBlock.php" hash="a5cc4138343b12f9331ef54680d7648d"/><dir name="CmsPage"><file name="Observer.php" hash="17672e5a375a845016ed6786822e7338"/></dir><file name="CmsPage.php" hash="9d7f3a47f86010f3a29ed6159f4cb21c"/><file name="EavEntityInterface.php" hash="2480d0ab4c3a2fcd932e6eaa14fa379d"/><file name="Interface.php" hash="aaddbbc90f8b79c8dd62a1da8c6e885c"/><file name="Localization.php" hash="34c39d389f49cc0610289abc300e587a"/><dir name="Product"><file name="Observer.php" hash="c601193795d6f6b816c4a497795a235e"/></dir><file name="Product.php" hash="238511ce9a9ff046d190ead5bc1a1614"/><file name="Types.php" hash="c5733a64f29f7757b579ed3db0035941"/></dir><file name="Content.php" hash="5b42268b986858f4e2553644859f0157"/><dir name="Localization"><dir name="Files"><file name="Index.php" hash="251ed711edae0b341c1a5efae675d7e8"/><file name="Observer.php" hash="41ee19ed96a8e89fd7996345dbeefc81"/></dir><file name="Files.php" hash="dfe0dea603339bfe26dbd39cf7d851ef"/></dir><dir name="Projects"><dir name="Filter"><file name="Attribute.php" hash="55d155fa86f130bdafbf327c90c5e835"/><file name="Category.php" hash="223d68bad9c803a702a7d9af1608c69c"/><file name="CmsBlock.php" hash="997bcc9a7e5fed8cc1ab83ab857fe9df"/><file name="CmsPage.php" hash="2b3ff753dcf1b433823421d190da71b9"/><file name="Localization.php" hash="2eefc6e303c5ac215e872a338eb18bbe"/><file name="Product.php" hash="e575bfdd0d305a2450eee70ff3dd3ab4"/></dir><file name="Filter.php" hash="76162256fed55b45de8a8f29e7dc3098"/><file name="Locales.php" hash="b6cc875cc0566be4e1a2319821cb29e7"/></dir><file name="Projects.php" hash="3363ec58337303078ba425a1d2a6f5d0"/><file name="Request.php" hash="a3f44f2a976ef111a019066c50f57f17"/><dir name="Resource"><dir name="Content"><file name="Collection.php" hash="c9023edbba4e58ae94ce28abdeeaebfb"/><dir name="Types"><file name="Collection.php" hash="76a3c493713870b715f0bda03ac8bdbf"/></dir><file name="Types.php" hash="f79d59987f6f4704b78624ee9b96a322"/></dir><file name="Content.php" hash="fd2f75acf4dde56a3493fd8b1aaf2ffd"/><dir name="Localization"><dir name="Files"><dir name="Index"><file name="Collection.php" hash="e70c65942fbab2421fac46d50dcd9917"/></dir><file name="Index.php" hash="316cb9392d6dc069995cde7f3a383bb7"/></dir></dir><dir name="Log"><file name="Collection.php" hash="da9e72b83246a2702ec61337e3794251"/></dir><dir name="Projects"><file name="Collection.php" hash="1b8eb944c1256501ae5ee8510d6eb652"/><dir name="Locales"><file name="Collection.php" hash="e33fcb38e5adebb6fcf6b6e51e00d07c"/></dir><file name="Locales.php" hash="495b859c4923614e1336964cf7fa9fdd"/></dir><file name="Projects.php" hash="6e6056e572c249fb02891227559b9e5e"/><dir name="Translate"><dir name="Attributes"><file name="Collection.php" hash="51d76f269666397e593c6e0549af0b12"/></dir><file name="Attributes.php" hash="c60775ed7cf40076dc6fb4eca0e16e38"/><dir name="Fields"><file name="Collection.php" hash="3c2d9e6d664e49f5d955cd073564493a"/><dir name="List"><dir name="Block"><file name="Collection.php" hash="ae829e8d41b5557da45dbf586c27f7f7"/></dir><file name="Collection.php" hash="a39fc10bf17fb8d3c5dd0cf6be265813"/><dir name="Page"><file name="Collection.php" hash="375f6c0ea41ff282b165957f1e6d26a7"/></dir></dir></dir><file name="Fields.php" hash="69f21286cd6148dd9d9ee70a8febe210"/></dir></dir><dir name="Service"><file name="Observer.php" hash="181230138b778c8cce45a37873f1bbd5"/></dir><file name="Service.php" hash="f2c61200e3c2e6aab661778fbe31d7f7"/><file name="SmartlingAPI.php" hash="2e773e2c24f0a1e89ff2fc4dc07d6c0c"/><dir name="Source"><dir name="Content"><dir name="Attributes"><file name="Category.php" hash="733afe33b777c218ea2fc1a0d3f24057"/><file name="Product.php" hash="65e6ec49cff665380c8b48a20f07da7b"/></dir><dir name="Fields"><file name="CmsBlock.php" hash="92951f0a2b6b0fa5a4ac12b2a73f7999"/><file name="CmsPage.php" hash="ddfa72f23f2814d025e37be58f45708c"/></dir><file name="Status.php" hash="2c217f66728d91bef7c1a3d02cf0995f"/><file name="Stores.php" hash="5c491599ec4b028a377ed5e6929f134e"/><file name="Types.php" hash="ced90b35a28adcf7bdd925f3d20f17c8"/></dir><dir name="Log"><file name="Level.php" hash="be291aca210ad45b21a23b634031dc8f"/></dir><file name="Projects.php" hash="75481bbe525cf44d7b328c6bd922609c"/><file name="Stores.php" hash="7db3da25ebd3d5e8c1abc965e7c0a7c8"/><file name="Types.php" hash="2890905d0bc1f03a023617186de71d3c"/><file name="Websites.php" hash="6e453a88980b9637e93aafc31e249cca"/></dir><dir name="Translate"><file name="Attributes.php" hash="04e910df7afc27ea7dbd5a841f6681cb"/><file name="Fields.php" hash="ed6e02de832c8114fb872da3bfe22d86"/><file name="StatusInterface.php" hash="3a803cb33867d754e8397fb3a3af388c"/></dir><dir name="Translator"><file name="Observer.php" hash="73bf8a3251e44dd643cfe73978b9e4a6"/></dir><file name="Translator.php" hash="50d8f9f9cda838d8e9125e9326e14db9"/><dir name="Types"><file name="Abstract.php" hash="bae6d4d967adf7393f34c269fd568a04"/><file name="Content.php" hash="3b6daf0b62c026b894e099d0f19d5aad"/><file name="General.php" hash="c5f9337752d8966b630f5fd46898451e"/><file name="Htmlcontent.php" hash="7f486871030abf1d2cc7e1af080e5786"/><file name="List.php" hash="befd42b05cf9fd0604bc38a6ce77ca7e"/><file name="Xml.php" hash="db18e977f815b06b8dd0a69a05a350b3"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="AttributesController.php" hash="636cf0a623e1c6ff0a4f390ae94c2736"/><file name="FieldsController.php" hash="f851d23ceaa96cf56372f4aa6c28e983"/><file name="InstanceController.php" hash="742d89c4895f8a7e617b4818fb33eefb"/><file name="ProjectsController.php" hash="0282657624681038240c2688a5706f2d"/><file name="ServiceController.php" hash="a9a024560d47ca1cb48a27fa42d6774a"/><dir name="Translator"><file name="CategoryController.php" hash="ef2b213dd34d0e04c9b5826bc6f6aa8f"/><file name="CmsBlockController.php" hash="225b47f491caa7abf4e2fab29501dedc"/><file name="CmsPageController.php" hash="1d52d8c889afae8ed8c4a8ab837b3a03"/><file name="LocalizationController.php" hash="552d6d86cba8b0b7a2cc6c5ee9979e9e"/><file name="ProductController.php" hash="25c7f8f75ddc6a22b6d7a37a40d76258"/></dir><file name="TranslatorController.php" hash="9e5ffe68533569e47ff2bb9198f223d3"/></dir><file name="ServiceController.php" hash="181d633ea44bd4dd702ad1927fbb2a91"/></dir><dir name="etc"><file name="adminhtml.xml" hash="b8e39f9357a3f42cbbd4f28f5466eaea"/><file name="config.xml" hash="cc513f879f5a6d5a03768e3c7fcac99e"/><file name="system.xml" hash="0f9ed07573762479ad172d06dfca3a6f"/></dir><dir name="sql"><dir name="smartling_setup"><file name="install-1.0.0.php" hash="31fa54a806011451d117706869d91567"/></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="smartling"><file name="check_statuses.js" hash="6cf4f9a710b24002852a6e7b9e389490"/><file name="content.js" hash="1e330ab524a3a59d4f25eafa5615144e"/><file name="locales_bulk_validation.js" hash="659dea3c2dca627310d36258e5cd3b1a"/><file name="locales_validation.js" hash="ada3187fa734aec10a85d6c8807fc587"/><file name="select_all.js" hash="e75591c30fe7202cc1b5ead272f7f8b3"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="smartling"><dir name="StyleSheet"><file name="bars.css" hash="32b0e3145b7a6365ab79d3e4f7672d71"/></dir><dir name="images"><file name="changed.png" hash="0af2e0da383b6b85fa521b2f65014deb"/><file name="inprogress.png" hash="84f1ab7032353f881b74389d17be1fb0"/><file name="sm_loader.gif" hash="0112fcb88b4bb3586e4feaf6ce58d3ce"/><file name="translated.png" hash="9159334289e3f1c062fe477504028f15"/><file name="wait.png" hash="8e9db28c39a7146ec326148a6d2511f1"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="smartling"><file name="translator.xml" hash="9065e28833e9c925d9941c1baab59430"/></dir></dir><dir name="template"><dir name="connector"><dir name="adminhtml"><dir name="edit"><dir name="tab"><file name="bulk_translations.phtml" hash="89c360582c32db05ad1ffebd1795f015"/><file name="translations.phtml" hash="f30256c72c6b6733105fd5efb9619b18"/></dir></dir><dir name="logs"><file name="view.phtml" hash="3605b4e8fb3d3537b87d61baeef0b85d"/></dir><dir name="system"><dir name="config"><file name="connectionbutton.phtml" hash="07390a013b9f8f376fff1776ccff725a"/><file name="contentfields.phtml" hash="564c454d4dc205bcad418bb341bab148"/></dir></dir><dir name="widget"><dir name="grid"><file name="massaction.phtml" hash="fbd81a3c40f4e52d09275ba41b6c79e0"/><file name="scripts_wraper.phtml" hash="39cf82017dad5666f8fea004c04d65da"/><file name="translate_status.phtml" hash="93f527ae52c0de0d4ff57b5713415e4c"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Smartling_Connector.xml" hash="8c970c5042daeedff7222d56c7c08992"/></dir></target></contents>
27
+ <compatible/>
28
+ <dependencies><required><php><min>5.1.1</min><max>5.5.9</max></php></required></dependencies>
29
+ </package>
skin/adminhtml/default/default/smartling/StyleSheet/bars.css ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bar-loading { background-image:url(../images/sm_loader.gif); background-repeat:no-repeat;}
2
+ .bar-default-wraper {
3
+ background-color:#fff;
4
+ border:solid 1px #999999;
5
+ width:133px;
6
+ height: 15px;
7
+ border-radius:3px;
8
+ float:left;
9
+ }
10
+ .bar-status {
11
+ background-color:#70aebf;
12
+ height:100%;
13
+ display:none;
14
+ }
15
+ .cell-percent {
16
+ width:25%;
17
+ text-align:center;
18
+ float:right;
19
+ }
skin/adminhtml/default/default/smartling/images/changed.png ADDED
Binary file
skin/adminhtml/default/default/smartling/images/inprogress.png ADDED
Binary file
skin/adminhtml/default/default/smartling/images/sm_loader.gif ADDED
Binary file
skin/adminhtml/default/default/smartling/images/translated.png ADDED
Binary file
skin/adminhtml/default/default/smartling/images/wait.png ADDED
Binary file