Flagbit_Factfinder - Version 4.1.1

Version Notes

Release

Download this release

Release Info

Developer FACTFinder
Extension Flagbit_Factfinder
Version 4.1.1
Comparing to
See all releases


Code changes from version 3.5.5 to 4.1.1

Files changed (262) hide show
  1. app/code/community/FACTFinder/Asn/Block/Catalog/Layer/Factfinder.php +64 -0
  2. app/code/community/FACTFinder/Asn/Block/Catalog/Layer/State.php +47 -0
  3. app/code/community/FACTFinder/Asn/Block/Catalog/Product/List/Toolbar.php +59 -0
  4. app/code/community/FACTFinder/Asn/Block/Catalog/Product/Pager.php +58 -0
  5. app/code/community/FACTFinder/Asn/Helper/Data.php +93 -0
  6. app/code/community/FACTFinder/Asn/Model/Catalog/Layer.php +48 -0
  7. app/code/community/FACTFinder/Asn/Model/Handler/Search.php +365 -0
  8. app/code/community/FACTFinder/Asn/Model/Layer/Filter/Factfinder.php +138 -0
  9. app/code/community/FACTFinder/Asn/Model/Layer/Filter/Item.php +118 -0
  10. app/code/community/FACTFinder/Asn/Model/Observer.php +126 -0
  11. app/code/community/FACTFinder/Asn/Model/Resource/Product/Attribute/Collection.php +181 -0
  12. app/code/community/FACTFinder/Asn/Model/Resource/Search/Collection.php +38 -0
  13. app/code/community/FACTFinder/Asn/etc/config.xml +82 -0
  14. app/code/community/FACTFinder/Asn/etc/system.xml +34 -0
  15. app/code/community/FACTFinder/Campaigns/Block/Abstract.php +78 -0
  16. app/code/community/FACTFinder/Campaigns/Block/Advisory/Product.php +87 -0
  17. app/code/community/FACTFinder/Campaigns/Block/Advisory/Search.php +50 -0
  18. app/code/community/FACTFinder/Campaigns/Block/Feedback/Abstract.php +49 -0
  19. app/code/community/FACTFinder/Campaigns/Block/Feedback/Cart.php +30 -0
  20. app/code/community/FACTFinder/Campaigns/Block/Feedback/Product.php +42 -0
  21. app/code/community/FACTFinder/Campaigns/Block/Feedback/Search.php +27 -0
  22. app/code/community/FACTFinder/Campaigns/Block/Pushed/Abstract.php +128 -0
  23. app/code/community/FACTFinder/Campaigns/Block/Pushed/Cart.php +28 -0
  24. app/code/community/FACTFinder/Campaigns/Block/Pushed/Product.php +42 -0
  25. app/code/community/FACTFinder/Campaigns/Block/Pushed/Search.php +46 -0
  26. app/code/community/FACTFinder/Campaigns/Helper/Data.php +63 -0
  27. app/code/community/FACTFinder/Campaigns/Model/Facade.php +67 -0
  28. app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php +155 -0
  29. app/code/community/FACTFinder/Campaigns/Model/Handler/Cart.php +70 -0
  30. app/code/community/FACTFinder/Campaigns/Model/Handler/Product.php +65 -0
  31. app/code/community/FACTFinder/Campaigns/Model/Handler/Search.php +71 -0
  32. app/code/community/FACTFinder/Campaigns/Model/Observer.php +71 -0
  33. app/code/community/FACTFinder/Campaigns/Model/Resource/Pushedproducts/Collection.php +191 -0
  34. app/code/community/FACTFinder/Campaigns/etc/config.xml +68 -0
  35. app/code/community/FACTFinder/Campaigns/etc/system.xml +43 -0
  36. app/code/community/FACTFinder/Core/Block/Adminhtml/Exportlink.php +131 -0
  37. app/code/community/FACTFinder/Core/Block/Adminhtml/Form/Field/Attribute.php +87 -0
  38. app/code/community/FACTFinder/Core/Block/Adminhtml/Form/Field/Attributes.php +88 -0
  39. app/code/community/FACTFinder/Core/Block/Catalog/Product/List/Toolbar.php +280 -0
  40. app/code/community/FACTFinder/Core/Block/Catalog/Product/Pager.php +90 -0
  41. app/code/community/{Flagbit/FactFinder → FACTFinder/Core}/Helper/Backend.php +248 -228
  42. app/code/community/FACTFinder/Core/Helper/Data.php +158 -0
  43. app/code/community/FACTFinder/Core/Helper/Debug.php +192 -0
  44. app/code/community/FACTFinder/Core/Helper/Search.php +200 -0
  45. app/code/community/FACTFinder/Core/Model/Autoloader.php +71 -0
  46. app/code/community/FACTFinder/Core/Model/CatalogSearch/Layer.php +51 -0
  47. app/code/community/FACTFinder/Core/Model/Export/Price.php +148 -0
  48. app/code/community/FACTFinder/Core/Model/Export/Product.php +1082 -0
  49. app/code/community/FACTFinder/Core/Model/Export/Stock.php +150 -0
  50. app/code/community/FACTFinder/Core/Model/Facade.php +708 -0
  51. app/code/community/FACTFinder/Core/Model/File.php +135 -0
  52. app/code/community/FACTFinder/Core/Model/Handler/Abstract.php +74 -0
  53. app/code/community/FACTFinder/Core/Model/Handler/Search.php +280 -0
  54. app/code/community/FACTFinder/Core/Model/Handler/Status.php +287 -0
  55. app/code/community/FACTFinder/Core/Model/Observer.php +270 -0
  56. app/code/community/FACTFinder/Core/Model/Resource/Search/Collection.php +145 -0
  57. app/code/community/FACTFinder/Core/Model/Resource/Search/Engine.php +41 -0
  58. app/code/community/FACTFinder/Core/Model/System/Config/Backend/Attributes.php +53 -0
  59. app/code/community/FACTFinder/Core/Model/System/Config/Backend/Cron.php +76 -0
  60. app/code/community/FACTFinder/Core/Model/System/Config/Backend/Enabled.php +85 -0
  61. app/code/community/FACTFinder/Core/Model/System/Config/Source/Authtype.php +54 -0
  62. app/code/community/FACTFinder/Core/Model/System/Config/Source/Identifier.php +48 -0
  63. app/code/community/FACTFinder/Core/Model/System/Config/Source/Protocol.php +48 -0
  64. app/code/community/FACTFinder/Core/controllers/ExportController.php +241 -0
  65. app/code/community/FACTFinder/Core/etc/adminhtml.xml +35 -0
  66. app/code/community/FACTFinder/Core/etc/config.xml +184 -0
  67. app/code/community/{Flagbit/FactFinder → FACTFinder/Core}/etc/system.xml +441 -397
  68. app/code/community/FACTFinder/Recommendation/Helper/Data.php +46 -0
  69. app/code/community/FACTFinder/Recommendation/Model/Facade.php +74 -0
  70. app/code/community/FACTFinder/Recommendation/Model/Handler/Recommendations.php +126 -0
  71. app/code/community/FACTFinder/Recommendation/Model/Observer.php +168 -0
  72. app/code/community/FACTFinder/Recommendation/etc/config.xml +59 -0
  73. app/code/community/FACTFinder/Recommendation/etc/system.xml +23 -0
  74. app/code/community/FACTFinder/Suggest/Block/TopSearch.php +50 -0
  75. app/code/community/{Flagbit/FactFinder → FACTFinder/Suggest}/Block/XmlConnect/Catalog/Search/Suggest.php +65 -58
  76. app/code/community/FACTFinder/Suggest/Helper/Data.php +83 -0
  77. app/code/community/FACTFinder/Suggest/Model/Facade.php +82 -0
  78. app/code/community/FACTFinder/Suggest/Model/Handler/Suggest.php +192 -0
  79. app/code/community/FACTFinder/Suggest/Model/Observer.php +64 -0
  80. app/code/community/FACTFinder/Suggest/Model/Processor.php +302 -0
  81. app/code/community/FACTFinder/Suggest/Model/System/Config/Source/Imagetype.php +50 -0
  82. app/code/community/FACTFinder/Suggest/controllers/ProxyController.php +44 -0
  83. app/code/community/FACTFinder/Suggest/etc/config.xml +97 -0
  84. app/code/community/FACTFinder/Suggest/etc/system.xml +89 -0
  85. app/code/community/FACTFinder/Tagcloud/Block/TagCloud.php +89 -0
  86. app/code/community/FACTFinder/Tagcloud/Helper/Data.php +27 -0
  87. app/code/community/FACTFinder/Tagcloud/Model/Facade.php +70 -0
  88. app/code/community/FACTFinder/Tagcloud/Model/Handler/TagCloud.php +117 -0
  89. app/code/community/FACTFinder/Tagcloud/etc/config.xml +47 -0
  90. app/code/community/FACTFinder/Tracking/Block/Init.php +101 -0
  91. app/code/community/FACTFinder/Tracking/Helper/Data.php +59 -0
  92. app/code/community/FACTFinder/Tracking/Model/Facade.php +40 -0
  93. app/code/community/FACTFinder/Tracking/Model/Handler/Tracking.php +207 -0
  94. app/code/community/FACTFinder/Tracking/Model/Observer.php +279 -0
  95. app/code/community/FACTFinder/Tracking/Model/Processor.php +106 -0
  96. app/code/community/FACTFinder/Tracking/Model/Queue.php +39 -0
  97. app/code/community/FACTFinder/Tracking/Model/Resource/Queue.php +39 -0
  98. app/code/community/FACTFinder/Tracking/Model/Resource/Queue/Collection.php +40 -0
  99. app/code/community/FACTFinder/Tracking/controllers/ProxyController.php +39 -0
  100. app/code/community/FACTFinder/Tracking/etc/config.xml +151 -0
  101. app/code/community/FACTFinder/Tracking/etc/system.xml +66 -0
  102. app/code/community/FACTFinder/Tracking/sql/factfinder_tracking_setup/mysql4-install-1.0.0.php +49 -0
  103. app/code/community/Flagbit/FactFinder/Block/Adminhtml/Cockpit.php +0 -33
  104. app/code/community/Flagbit/FactFinder/Block/Adminhtml/Exportlink.php +0 -64
  105. app/code/community/Flagbit/FactFinder/Block/Adminhtml/Form/Field/Attribute.php +0 -54
  106. app/code/community/Flagbit/FactFinder/Block/Adminhtml/Form/Field/Attributes.php +0 -85
  107. app/code/community/Flagbit/FactFinder/Block/Campaign/Advisory.php +0 -32
  108. app/code/community/Flagbit/FactFinder/Block/Campaign/Cart/Advisory.php +0 -63
  109. app/code/community/Flagbit/FactFinder/Block/Campaign/Cart/Feedback.php +0 -67
  110. app/code/community/Flagbit/FactFinder/Block/Campaign/Feedback.php +0 -71
  111. app/code/community/Flagbit/FactFinder/Block/Campaign/Product/Advisory.php +0 -54
  112. app/code/community/Flagbit/FactFinder/Block/Campaign/Product/Feedback.php +0 -51
  113. app/code/community/Flagbit/FactFinder/Block/Cart/Crosssell.php +0 -92
  114. app/code/community/Flagbit/FactFinder/Block/Filter/Slider.php +0 -36
  115. app/code/community/Flagbit/FactFinder/Block/Layer.php +0 -154
  116. app/code/community/Flagbit/FactFinder/Block/Layer/Abstract.php +0 -33
  117. app/code/community/Flagbit/FactFinder/Block/Product/List/Crosssell.php +0 -74
  118. app/code/community/Flagbit/FactFinder/Block/Product/List/Upsell.php +0 -142
  119. app/code/community/Flagbit/FactFinder/Block/Secondaryresult.php +0 -31
  120. app/code/community/Flagbit/FactFinder/Block/TagCloud.php +0 -54
  121. app/code/community/Flagbit/FactFinder/Block/Tracking.php +0 -108
  122. app/code/community/Flagbit/FactFinder/Block/XmlConnect/Catalog/Product/List.php +0 -134
  123. app/code/community/Flagbit/FactFinder/Block/XmlConnect/Catalog/Search.php +0 -133
  124. app/code/community/Flagbit/FactFinder/Helper/Data.php +0 -73
  125. app/code/community/Flagbit/FactFinder/Helper/Debug.php +0 -140
  126. app/code/community/Flagbit/FactFinder/Helper/Search.php +0 -421
  127. app/code/community/Flagbit/FactFinder/Model/Export/Price.php +0 -91
  128. app/code/community/Flagbit/FactFinder/Model/Export/Product.php +0 -616
  129. app/code/community/Flagbit/FactFinder/Model/Export/Stock.php +0 -91
  130. app/code/community/Flagbit/FactFinder/Model/Facade.php +0 -549
  131. app/code/community/Flagbit/FactFinder/Model/Handler/Abstract.php +0 -45
  132. app/code/community/Flagbit/FactFinder/Model/Handler/CheckStatus.php +0 -150
  133. app/code/community/Flagbit/FactFinder/Model/Handler/ProductCampaign.php +0 -75
  134. app/code/community/Flagbit/FactFinder/Model/Handler/ProductDetailCampaign.php +0 -27
  135. app/code/community/Flagbit/FactFinder/Model/Handler/Recommendations.php +0 -51
  136. app/code/community/Flagbit/FactFinder/Model/Handler/Search.php +0 -435
  137. app/code/community/Flagbit/FactFinder/Model/Handler/SecondarySearch.php +0 -94
  138. app/code/community/Flagbit/FactFinder/Model/Handler/ShoppingCartCampaign.php +0 -27
  139. app/code/community/Flagbit/FactFinder/Model/Handler/Suggest.php +0 -106
  140. app/code/community/Flagbit/FactFinder/Model/Handler/TagCloud.php +0 -71
  141. app/code/community/Flagbit/FactFinder/Model/Handler/Tracking.php +0 -64
  142. app/code/community/Flagbit/FactFinder/Model/Handler/Tracking/Scic.php +0 -77
  143. app/code/community/Flagbit/FactFinder/Model/Layer.php +0 -83
  144. app/code/community/Flagbit/FactFinder/Model/Layer/Abstract.php +0 -7
  145. app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Abstract.php +0 -118
  146. app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Catalog.php +0 -25
  147. app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Catalogsearch.php +0 -35
  148. app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Item.php +0 -23
  149. app/code/community/Flagbit/FactFinder/Model/Mysql4/Campaign/Pushedproducts/Collection.php +0 -148
  150. app/code/community/Flagbit/FactFinder/Model/Mysql4/Product/Attribute/Collection.php +0 -144
  151. app/code/community/Flagbit/FactFinder/Model/Mysql4/Product/Recommendation/Collection.php +0 -59
  152. app/code/community/Flagbit/FactFinder/Model/Mysql4/Scic/Queue.php +0 -31
  153. app/code/community/Flagbit/FactFinder/Model/Mysql4/Scic/Queue/Collection.php +0 -28
  154. app/code/community/Flagbit/FactFinder/Model/Mysql4/Search/Collection.php +0 -135
  155. app/code/community/Flagbit/FactFinder/Model/Mysql4/Search/Engine.php +0 -53
  156. app/code/community/Flagbit/FactFinder/Model/Observer.php +0 -394
  157. app/code/community/Flagbit/FactFinder/Model/Processor.php +0 -281
  158. app/code/community/Flagbit/FactFinder/Model/Scic/Queue.php +0 -27
  159. app/code/community/Flagbit/FactFinder/Model/System/Config/Backend/Attributes.php +0 -52
  160. app/code/community/Flagbit/FactFinder/Model/System/Config/Backend/Enabled.php +0 -57
  161. app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Authtype.php +0 -45
  162. app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Ffversion.php +0 -53
  163. app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Identifier.php +0 -41
  164. app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Imagetype.php +0 -37
  165. app/code/community/Flagbit/FactFinder/controllers/Adminhtml/Factfinder/CockpitController.php +0 -53
  166. app/code/community/Flagbit/FactFinder/controllers/ExportController.php +0 -141
  167. app/code/community/Flagbit/FactFinder/controllers/ProxyController.php +0 -52
  168. app/code/community/Flagbit/FactFinder/etc/adminhtml.xml +0 -49
  169. app/code/community/Flagbit/FactFinder/etc/config.xml +0 -313
  170. app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-install-3.2.0.php +0 -38
  171. app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-upgrade-3.2.0-3.2.1.php +0 -30
  172. app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-upgrade-3.2.1-3.3.0.php +0 -34
  173. app/design/adminhtml/default/default/layout/factfinder.xml +0 -28
  174. app/design/adminhtml/default/default/template/factfinder/cockpit.phtml +0 -22
  175. app/design/frontend/base/default/layout/factfinder.xml +0 -78
  176. app/design/frontend/base/default/layout/factfinder/asn.xml +38 -0
  177. app/design/frontend/base/default/layout/factfinder/campaigns.xml +120 -0
  178. app/design/frontend/base/default/layout/factfinder/core.xml +54 -0
  179. app/design/frontend/base/default/layout/factfinder/suggest.xml +28 -0
  180. app/design/frontend/base/default/layout/factfinder/tagcloud.xml +21 -0
  181. app/design/frontend/base/default/layout/factfinder/tracking.xml +24 -0
  182. app/design/frontend/base/default/template/factfinder/asn/layer/filter/slider.phtml +41 -0
  183. app/design/frontend/base/default/template/factfinder/asn/layer/slider.phtml +18 -0
  184. app/design/frontend/base/default/template/factfinder/campaign/advisory.phtml +0 -12
  185. app/design/frontend/base/default/template/factfinder/campaign/cart/advisory.phtml +0 -12
  186. app/design/frontend/base/default/template/factfinder/campaign/cart/feedback.phtml +0 -6
  187. app/design/frontend/base/default/template/factfinder/campaign/feedback.phtml +0 -11
  188. app/design/frontend/base/default/template/factfinder/campaign/product/advisory.phtml +0 -13
  189. app/design/frontend/base/default/template/factfinder/campaign/product/feedback.phtml +0 -7
  190. app/design/frontend/base/default/template/factfinder/campaigns/advisory.phtml +32 -0
  191. app/design/frontend/base/default/template/factfinder/campaigns/feedback.phtml +15 -0
  192. app/design/frontend/base/default/template/factfinder/campaigns/pushed.phtml +43 -0
  193. app/design/frontend/base/default/template/factfinder/core/export/locked.phtml +19 -0
  194. app/design/frontend/base/default/template/factfinder/core/export/nofile.phtml +19 -0
  195. app/design/frontend/base/default/template/factfinder/filter/scriptaculousSlider.phtml +0 -103
  196. app/design/frontend/base/default/template/factfinder/filter/slider.phtml +0 -46
  197. app/design/frontend/base/default/template/factfinder/form.advancedsuggest.phtml +0 -97
  198. app/design/frontend/base/default/template/factfinder/form.advancedsuggest68.phtml +0 -111
  199. app/design/frontend/base/default/template/factfinder/form.mini.phtml +0 -54
  200. app/design/frontend/base/default/template/factfinder/logo.phtml +0 -22
  201. app/design/frontend/base/default/template/factfinder/secondaryresult.phtml +0 -41
  202. app/design/frontend/base/default/template/factfinder/suggest/advancedsuggest.phtml +57 -0
  203. app/design/frontend/base/default/template/factfinder/tracking.phtml +0 -33
  204. app/design/frontend/base/default/template/factfinder/tracking/init.phtml +26 -0
  205. app/etc/factfinder.xml +2 -20
  206. app/etc/modules/Flagbit_FactFinder.xml +0 -9
  207. app/locale/de_DE/Flagbit_FactFinder.csv +0 -91
  208. js/factfinder/jXHR.js +10 -10
  209. js/factfinder/suggest.js +127 -6
  210. js/factfinder/tracking.js +73 -61
  211. lib/FACTFinder/Abstract/Adapter.php +0 -134
  212. lib/FACTFinder/Abstract/Configuration.php +0 -223
  213. lib/FACTFinder/Abstract/DataProvider.php +0 -125
  214. lib/FACTFinder/Abstract/Logger.php +0 -23
  215. lib/FACTFinder/Adapter/AbstractAdapter.php +194 -0
  216. lib/FACTFinder/Adapter/Compare.php +179 -0
  217. lib/FACTFinder/Adapter/Import.php +100 -0
  218. lib/FACTFinder/Adapter/ProductCampaign.php +301 -0
  219. lib/FACTFinder/Adapter/Recommendation.php +212 -0
  220. lib/FACTFinder/Adapter/Search.php +1001 -0
  221. lib/FACTFinder/Adapter/SimilarRecords.php +220 -0
  222. lib/FACTFinder/Adapter/Suggest.php +127 -0
  223. lib/FACTFinder/Adapter/TagCloud.php +116 -0
  224. lib/FACTFinder/Adapter/Tracking.php +383 -0
  225. lib/FACTFinder/AdvisorAnswer.php +0 -77
  226. lib/FACTFinder/AdvisorQuestion.php +0 -67
  227. lib/FACTFinder/Asn.php +0 -37
  228. lib/FACTFinder/AsnFilterItem.php +0 -72
  229. lib/FACTFinder/AsnGroup.php +0 -177
  230. lib/FACTFinder/AsnSliderFilter.php +0 -139
  231. lib/FACTFinder/BreadCrumbItem.php +0 -75
  232. lib/FACTFinder/Campaign.php +0 -206
  233. lib/FACTFinder/CampaignIterator.php +0 -190
  234. lib/FACTFinder/Configuration.php +0 -448
  235. lib/FACTFinder/Core/AbstractConfiguration.php +231 -0
  236. lib/FACTFinder/Core/AbstractEncodingConverter.php +156 -0
  237. lib/FACTFinder/Core/Client/RequestParser.php +185 -0
  238. lib/FACTFinder/Core/Client/UrlBuilder.php +77 -0
  239. lib/FACTFinder/Core/ConfigurationInterface.php +212 -0
  240. lib/FACTFinder/Core/IConvEncodingConverter.php +40 -0
  241. lib/FACTFinder/Core/ManualConfiguration.php +197 -0
  242. lib/FACTFinder/Core/Page/.gitignore +0 -0
  243. lib/FACTFinder/Core/ParametersConverter.php +158 -0
  244. lib/FACTFinder/Core/Server/AbstractDataProvider.php +111 -0
  245. lib/FACTFinder/Core/Server/ConnectionData.php +202 -0
  246. lib/FACTFinder/Core/Server/EasyCurlDataProvider.php +230 -0
  247. lib/FACTFinder/Core/Server/EasyCurlRequestFactory.php +79 -0
  248. lib/FACTFinder/Core/Server/FileSystemDataProvider.php +121 -0
  249. lib/FACTFinder/Core/Server/FileSystemRequestFactory.php +70 -0
  250. lib/FACTFinder/Core/Server/MultiCurlDataProvider.php +346 -0
  251. lib/FACTFinder/Core/Server/MultiCurlRequestFactory.php +79 -0
  252. lib/FACTFinder/Core/Server/NullResponse.php +16 -0
  253. lib/FACTFinder/Core/Server/Request.php +126 -0
  254. lib/FACTFinder/Core/Server/RequestFactoryInterface.php +14 -0
  255. lib/FACTFinder/Core/Server/Response.php +72 -0
  256. lib/FACTFinder/Core/Server/UrlBuilder.php +229 -0
  257. lib/FACTFinder/Core/Utf8EncodingConverter.php +50 -0
  258. lib/FACTFinder/Core/XmlConfiguration.php +349 -0
  259. lib/FACTFinder/Curl.php +0 -99
  260. lib/FACTFinder/CurlHandle.php +0 -8
  261. lib/FACTFinder/CurlInterface.php +0 -25
  262. lib/FACTFinder/CurlStub.php +0 -375
app/code/community/FACTFinder/Asn/Block/Catalog/Layer/Factfinder.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Asn_Block_Catalog_Layer_Factfinder
16
+ *
17
+ * Replaces default layer filter attribute
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Asn
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Asn_Block_Catalog_Layer_Factfinder extends Mage_Catalog_Block_Layer_Filter_Attribute
27
+ {
28
+ const TYPE_SLIDER = 'slider';
29
+
30
+
31
+ /**
32
+ * Class constructor
33
+ * Here we just set our own model as filter model
34
+ */
35
+ public function __construct()
36
+ {
37
+ parent::__construct();
38
+ $this->_filterModelName = 'factfinder_asn/layer_filter_factfinder';
39
+ }
40
+
41
+
42
+ /**
43
+ * Initialize filter model object
44
+ * The only thing we need here is to set our own template for price filter
45
+ *
46
+ * @return FACTFinder_Asn_Block_Catalog_Layer_Factfinder
47
+ */
48
+ public function init()
49
+ {
50
+ parent::init();
51
+
52
+ $attribute = $this->getAttributeModel();
53
+ if ($attribute->getType() == self::TYPE_SLIDER) {
54
+ $this->setTemplate('factfinder/asn/layer/filter/slider.phtml');
55
+ $this->setData((current($attribute->getItems())));
56
+ $this->setUnit($attribute->getUnit());
57
+ $this->setLinkCount($attribute->getLinkCount());
58
+ }
59
+
60
+ return $this;
61
+ }
62
+
63
+
64
+ }
app/code/community/FACTFinder/Asn/Block/Catalog/Layer/State.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Asn_Block_Catalog_Layer_Factfinder
16
+ *
17
+ * Replaces default layer filter attribute
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Asn
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Asn_Block_Catalog_Layer_State extends Mage_Catalog_Block_Layer_State
27
+ {
28
+ /**
29
+ * Retrieve Clear Filters URL
30
+ *
31
+ * @return string
32
+ */
33
+ public function getClearUrl()
34
+ {
35
+ $currentParams = $this->getRequest()->getParams();
36
+ foreach($currentParams as $paramKey => $paramValue) {
37
+ if($paramKey != 'q') {
38
+ $currentParams[$paramKey] = null;
39
+ }
40
+ }
41
+ $params['_current'] = true;
42
+ $params['_use_rewrite'] = true;
43
+ $params['_query'] = $currentParams;
44
+ $params['_escape'] = true;
45
+ return Mage::getUrl('*/*/*', $params);
46
+ }
47
+ }
app/code/community/FACTFinder/Asn/Block/Catalog/Product/List/Toolbar.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Block_Catalog_Product_List_Toolbar
15
+ *
16
+ * Replaces default layer toolbar on navigation
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Asn
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Asn_Block_Catalog_Product_List_Toolbar extends FACTFinder_Core_Block_Catalog_Product_List_Toolbar
26
+ {
27
+
28
+
29
+ /**
30
+ * Constructor
31
+ *
32
+ * @return void
33
+ */
34
+ protected function _construct()
35
+ {
36
+ if (!Mage::helper('factfinder_asn')->isCatalogNavigation()) {
37
+ $this->_useFF = false;
38
+ }
39
+
40
+ parent::_construct();
41
+ }
42
+
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function getPagerUrl($params = array())
48
+ {
49
+ $url = parent::getPagerUrl($params);
50
+
51
+ if ($this->_handler && !Mage::helper('factfinder/search')->getIsOnSearchPage()) {
52
+ $url = Mage::helper('factfinder_asn')->removeCategoryParams($url);
53
+ }
54
+
55
+ return $url;
56
+ }
57
+
58
+
59
+ }
app/code/community/FACTFinder/Asn/Block/Catalog/Product/Pager.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Block_Catalog_Product_Pager
15
+ *
16
+ * Replaces default layer pager on navigation
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Asn
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Asn_Block_Catalog_Product_Pager extends FACTFinder_Core_Block_Catalog_Product_Pager
26
+ {
27
+
28
+
29
+ /**
30
+ * Constructor
31
+ *
32
+ * @return void
33
+ */
34
+ protected function _construct()
35
+ {
36
+ if (!Mage::helper('factfinder_asn')->isCatalogNavigation()) {
37
+ $this->_useFF = false;
38
+ }
39
+
40
+ parent::_construct();
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ */
46
+ public function getPagerUrl($params = array())
47
+ {
48
+ $url = parent::getPagerUrl($params);
49
+
50
+ if ($this->_handler && !Mage::helper('factfinder/search')->getIsOnSearchPage()) {
51
+ $url = Mage::helper('factfinder_asn')->removeCategoryParams($url);
52
+ }
53
+
54
+ return $url;
55
+ }
56
+
57
+
58
+ }
app/code/community/FACTFinder/Asn/Helper/Data.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Helper_Data
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Asn
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Asn_Helper_Data extends Mage_Core_Helper_Abstract
24
+ {
25
+
26
+
27
+ /**
28
+ * Parse url and return array of parameters
29
+ *
30
+ * @param string $url
31
+ *
32
+ * @return array
33
+ */
34
+ public function getQueryParams($url)
35
+ {
36
+ $queryParams = array();
37
+
38
+ //conserve url encoded spaces, since parse_str replaces them with underscores
39
+ $url = str_replace('%20', 'XXXXXXXXXX', $url);
40
+
41
+ $parseUrl = parse_url($url);
42
+ if (isset($parseUrl['query'])) {
43
+ parse_str($parseUrl['query'], $queryParams);
44
+ }
45
+
46
+ // recover spaces
47
+ // we use not encoded values since they will be encoded with Mage::getUrl()
48
+ $result = array();
49
+ foreach ($queryParams as $key => $value) {
50
+ $key = str_replace('XXXXXXXXXX', ' ', $key);
51
+ $value = str_replace('XXXXXXXXXX', ' ', $value);
52
+ $result[$key] = $value;
53
+ }
54
+
55
+ return $result;
56
+ }
57
+
58
+
59
+ /**
60
+ * Check is catalog navigation replacement is enabled
61
+ *
62
+ * @return bool
63
+ */
64
+ public function isCatalogNavigation()
65
+ {
66
+ return (bool) Mage::app()->getStore()->getConfig('factfinder/modules/catalog_navigation');
67
+ }
68
+
69
+
70
+ /**
71
+ * Remove category filter params if they are the save as the current category ones
72
+ *
73
+ * On catalog navigation if we use all the params from ff we have unnecessary ugly params
74
+ * which we don't need. This function removes them
75
+ *
76
+ * @param string $url
77
+ *
78
+ * @return mixed
79
+ */
80
+ public function removeCategoryParams($url)
81
+ {
82
+ $categoryPath = Mage::getSingleton('factfinder_asn/handler_search')->getCurrentFactFinderCategoryPath();
83
+ $query = http_build_query($categoryPath);
84
+ $query = str_replace('+', '%20', $query);
85
+ $url = str_replace($query, '', $url);
86
+ //remove redundant &
87
+ $url = str_replace(array('?&', '&&'), array('?', '&'), $url);
88
+
89
+ return $url;
90
+ }
91
+
92
+
93
+ }
app/code/community/FACTFinder/Asn/Model/Catalog/Layer.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Catalog_Layer
15
+ *
16
+ * Replaces standard layer model in order to use our own collection
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Asn
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Asn_Model_Catalog_Layer extends Mage_Catalog_Model_Layer
26
+ {
27
+
28
+
29
+ /**
30
+ * Get current layer product collection
31
+ *
32
+ * @return Mage_Catalog_Model_Resource_Product_Collection
33
+ */
34
+ public function getProductCollection()
35
+ {
36
+ if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
37
+ $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
38
+ } else {
39
+ $collection = Mage::getResourceModel('factfinder_asn/search_collection');
40
+ $this->prepareProductCollection($collection);
41
+ $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
42
+ }
43
+
44
+ return $collection;
45
+ }
46
+
47
+
48
+ }
app/code/community/FACTFinder/Asn/Model/Handler/Search.php ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Handler_Search
15
+ *
16
+ * Handle navigation data and data communications
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Asn
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Asn_Model_Handler_Search extends FACTFinder_Core_Model_Handler_Search
26
+ {
27
+
28
+ /**
29
+ * Navigation array from fact finder
30
+ *
31
+ * @var array
32
+ */
33
+ protected $_afterSearchNavigation = array();
34
+
35
+ /**
36
+ * @var array
37
+ */
38
+ protected $_currentFactFinderCategoryPath = array();
39
+
40
+
41
+ /**
42
+ * Get and format navigation array from fact finder
43
+ *
44
+ * @return array
45
+ */
46
+ public function getAfterSearchNavigation()
47
+ {
48
+ if (empty($this->_afterSearchNavigation) && $this->isSearchHasResult()) {
49
+ $result = $this->_getFacade()->getAfterSearchNavigation();
50
+
51
+ if ($result instanceof FACTFinder\Data\AfterSearchNavigation && count($result)) {
52
+ foreach ($result as $row) {
53
+ $this->_afterSearchNavigation[] = array(
54
+ 'attribute_code' => $row->getName(),
55
+ 'name' => $row->getName(),
56
+ 'unit' => $row->getUnit(),
57
+ 'items' => $this->_getAttributeOptions($row, $row->getUnit()),
58
+ 'count' => $row->count(),
59
+ 'type' => $this->_getFilterType($row),
60
+ 'store_label' => $row->getName(),
61
+ 'link_count' => $row->getDetailedLinkCount(),
62
+ 'is_multiselect' => $row->isMultiSelectStyle()
63
+ );
64
+ }
65
+ }
66
+ }
67
+
68
+ return $this->_afterSearchNavigation;
69
+ }
70
+
71
+
72
+ /**
73
+ * Get Attribute Options Array from FactFinder FilterGroupItems
74
+ *
75
+ * @param FACTFinder\Data\FilterGroup $filterGroup
76
+ *
77
+ * @return array
78
+ */
79
+ protected function _getAttributeOptions(FACTFinder\Data\FilterGroup $filterGroup)
80
+ {
81
+ $attributeOptions = array();
82
+
83
+ $currentCategoryPath = $this->getCurrentFactFinderCategoryPath();
84
+
85
+ foreach ($filterGroup as $option) {
86
+ $queryParams = Mage::helper('factfinder_asn')->getQueryParams($option->getUrl());
87
+ $queryParams = $this->_removeCategoriesFromParams($currentCategoryPath, $queryParams);
88
+
89
+ $filterValue = $this->_getAttributeOptionValue($option, $filterGroup);
90
+
91
+ $seoPath = '';
92
+ if (isset($queryParams['seoPath'])) {
93
+ $seoPath = $queryParams['seoPath'];
94
+ }
95
+
96
+ if ($this->_isOnSearchPage() || !empty($_filterValue)) {
97
+ unset($queryParams['seoPath']);
98
+ }
99
+
100
+ if ($filterGroup->isSliderStyle()) {
101
+ $queryParams['filter' . $option->getFieldName()] = $filterValue;
102
+ $attributeOptions[] = $this->_prepareSliderOption($option, $filterGroup, $queryParams);
103
+ } else {
104
+ if (!$option->getLabel() || $this->_isTopLevelNavigation($option, $currentCategoryPath)) {
105
+ continue;
106
+ }
107
+
108
+ $attributeOptionData = $this->_prepareOption($option, $filterGroup, $filterValue);
109
+ $attributeOptionData['seoPath'] = $seoPath;
110
+ $attributeOptionData['queryParams'] = $queryParams;
111
+
112
+ $attributeOptions[] = $attributeOptionData;
113
+ }
114
+ }
115
+
116
+ return $attributeOptions;
117
+ }
118
+
119
+
120
+ /**
121
+ * Check if this is a top level navigation option
122
+ *
123
+ * @param \FACTFinder\Data\Filter $option
124
+ * @param array $categoryPath
125
+ *
126
+ * @return bool
127
+ */
128
+ protected function _isTopLevelNavigation(FACTFinder\Data\Filter $option, $categoryPath)
129
+ {
130
+ if (!$this->_isOnSearchPage()
131
+ && strpos($option->getFieldName(), 'categoryROOT') !== false
132
+ && in_array($option->getLabel(), $categoryPath)
133
+ ) {
134
+ return true;
135
+ }
136
+
137
+ return false;
138
+ }
139
+
140
+
141
+ /**
142
+ * Remove current categories from query params
143
+ *
144
+ * @param array $categoryPath
145
+ * @param array $params
146
+ *
147
+ * @return array
148
+ */
149
+ protected function _removeCategoriesFromParams($categoryPath, $params)
150
+ {
151
+ if (!$this->_isOnSearchPage()) {
152
+ foreach ($categoryPath as $filterParam => $filterValue) {
153
+ if (isset($params[$filterParam])) {
154
+ unset($params[$filterParam]);
155
+ }
156
+ }
157
+
158
+ if (isset($params['q']) && Mage::app()->getRequest()->getModuleName() == 'catalog') {
159
+ unset($params['q']);
160
+ }
161
+ }
162
+
163
+ return $params;
164
+ }
165
+
166
+
167
+ /**
168
+ * Prepare option array for slider
169
+ *
170
+ * @param \FACTFinder\Data\SliderFilter $option
171
+ * @param \FACTFinder\Data\FilterGroup $filterGroup
172
+ * @param array $params
173
+ *
174
+ * @return array
175
+ */
176
+ protected function _prepareSliderOption(FACTFinder\Data\SliderFilter $option, $filterGroup, $params)
177
+ {
178
+ $option = array(
179
+ 'type' => 'number',
180
+ 'label' => 'slider',
181
+ 'value' => $this->_getAttributeOptionValue($option, $filterGroup),
182
+ 'absolute_min' => $option->getAbsoluteMinimum(),
183
+ 'absolute_max' => $option->getAbsoluteMaximum(),
184
+ 'selected_min' => $option->getSelectedMinimum(),
185
+ 'selected_max' => $option->getSelectedMaximum(),
186
+ 'count' => true,
187
+ 'selected' => false,
188
+ 'requestVar' => 'filter' . $option->getFieldName(),
189
+ 'queryParams' => $params
190
+ );
191
+
192
+ return $option;
193
+ }
194
+
195
+
196
+ /**
197
+ * Prepare normal option array
198
+ *
199
+ * @param \FACTFinder\Data\Filter $option
200
+ * @param \FACTFinder\Data\FilterGroup $filterGroup
201
+ * @param string $filterValue
202
+ *
203
+ * @return array
204
+ */
205
+ protected function _prepareOption(FACTFinder\Data\Filter $option, $filterGroup, $filterValue)
206
+ {
207
+ $label = $option->getLabel();
208
+ if ($filterGroup->getUnit()) {
209
+ $label .= ' ' . $filterGroup->getUnit();
210
+ }
211
+
212
+ $option = array(
213
+ 'type' => 'attribute',
214
+ 'label' => $label,
215
+ 'value' => $filterValue,
216
+ 'count' => $option->getMatchCount(),
217
+ 'selected' => $option->isSelected(),
218
+ 'clusterLevel' => $option->getClusterLevel(),
219
+ 'requestVar' => 'filter' . $option->getFieldName(),
220
+ 'previewImage' => $option->getPreviewImage()
221
+ );
222
+
223
+ return $option;
224
+ }
225
+
226
+
227
+ /**
228
+ * Check if we are on search page
229
+ *
230
+ * @return bool
231
+ */
232
+ protected function _isOnSearchPage()
233
+ {
234
+ return Mage::helper('factfinder/search')->getIsOnSearchPage();
235
+ }
236
+
237
+
238
+ /**
239
+ * Prepare current category path array
240
+ *
241
+ * @return array
242
+ */
243
+ public function getCurrentFactFinderCategoryPath()
244
+ {
245
+ if (empty($this->_currentFactFinderCategoryPath)) {
246
+
247
+ if (!Mage::registry('current_category')) {
248
+ return array();
249
+ }
250
+
251
+ /** @var $category Mage_Catalog_Model_Category */
252
+ $category = Mage::registry('current_category');
253
+
254
+ $pathInStore = $category->getPathInStore();
255
+ $pathIds = array_reverse(explode(',', $pathInStore));
256
+
257
+ $categories = $category->getParentCategories();
258
+ $mainCategoriesString = '';
259
+ foreach ($pathIds as $categoryId) {
260
+ if (!isset($categories[$categoryId]) || !$categories[$categoryId]->getName()) {
261
+ continue;
262
+ }
263
+
264
+ $categoryName = html_entity_decode($categories[$categoryId]->getName());
265
+ if (empty($mainCategoriesString)) {
266
+ $this->_currentFactFinderCategoryPath['filtercategoryROOT'] = $categoryName;
267
+ } else {
268
+ $this->_currentFactFinderCategoryPath['filtercategoryROOT' . $mainCategoriesString] = $categoryName;
269
+ }
270
+
271
+ $mainCategoriesString .= '/' . $this->_encodeSpecialCharacters($categoryName);
272
+ }
273
+ }
274
+
275
+ return $this->_currentFactFinderCategoryPath;
276
+ }
277
+
278
+
279
+ /**
280
+ * Get Attribute option Value
281
+ *
282
+ * @param FACTFinder\Data\Filter $option
283
+ * @param FACTFinder\Data\FilterGroup $filterGroup
284
+ *
285
+ * @return string
286
+ */
287
+ protected function _getAttributeOptionValue(FACTFinder\Data\Filter $option, $filterGroup)
288
+ {
289
+ $value = null;
290
+
291
+ if ($filterGroup->isSliderStyle()) {
292
+ $value = '[VALUE]';
293
+ } else {
294
+ $queryParams = Mage::helper('factfinder_asn')->getQueryParams($option->getUrl());
295
+
296
+ if (isset($queryParams['filter' . $option->getFieldName()])) {
297
+ $value = $queryParams['filter' . $option->getFieldName()];
298
+ } else {
299
+ $value = '';
300
+ }
301
+ }
302
+
303
+ return $value;
304
+ }
305
+
306
+
307
+ /**
308
+ * Get Filter Type by FACT-Finder FilterItem
309
+ *
310
+ * @param FACTFinder\Data\FilterGroup $options
311
+ *
312
+ * @return string
313
+ */
314
+ protected function _getFilterType(FACTFinder\Data\FilterGroup $options)
315
+ {
316
+ $type = 'text';
317
+ if ($options->isSliderStyle()) {
318
+ $type = 'slider';
319
+ }
320
+
321
+ return $type;
322
+ }
323
+
324
+
325
+ /**
326
+ * Prepare all request parameters for the search adapter
327
+ *
328
+ * @return array
329
+ */
330
+ protected function _collectParams()
331
+ {
332
+ $params = parent::_collectParams();
333
+
334
+ if (Mage::app()->getRequest()->getModuleName() == 'catalog') {
335
+ if (!Mage::app()->getRequest()->getParam('advisorStatus')) {
336
+ $params = array_merge($params, $this->getCurrentFactFinderCategoryPath());
337
+ }
338
+
339
+ $params['navigation'] = 'true';
340
+ }
341
+
342
+ return $params;
343
+ }
344
+
345
+
346
+ /**
347
+ * Encode special characters according to ff list
348
+ *
349
+ * @param string $categoryName
350
+ *
351
+ * @return string
352
+ */
353
+ protected function _encodeSpecialCharacters($categoryName)
354
+ {
355
+ $categoryName = str_replace(
356
+ array('%', '#', '|', '/', '=', '+'),
357
+ array('%25', '%23', '%7C', '%2F', '%3D', '%2B'),
358
+ $categoryName
359
+ );
360
+
361
+ return $categoryName;
362
+ }
363
+
364
+
365
+ }
app/code/community/FACTFinder/Asn/Model/Layer/Filter/Factfinder.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Layer_Filter_Factfinder
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Asn
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Asn_Model_Layer_Filter_Factfinder extends Mage_Catalog_Model_Layer_Filter_Abstract
24
+ {
25
+
26
+ /**
27
+ * Array of Magento Layer Filter Items
28
+ *
29
+ * @var mixed
30
+ */
31
+ protected $_filterItems = null;
32
+
33
+ /**
34
+ * Array of Selected Layer Filters
35
+ *
36
+ * @var mixed
37
+ */
38
+ protected $_selectedFilterItems = array();
39
+
40
+
41
+ /**
42
+ * Apply attribute option filter to product collection
43
+ *
44
+ * @param Zend_Controller_Request_Abstract $request
45
+ * @param Varien_Object $filterBlock
46
+ *
47
+ * @return Mage_Catalog_Model_Layer_Filter_Attribute
48
+ */
49
+ public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
50
+ {
51
+ $this->_getItemsData();
52
+ $_attributeCode = $filterBlock->getAttributeModel()->getAttributeCode();
53
+ if (isset($this->_selectedFilterItems[$_attributeCode])
54
+ && is_array($this->_selectedFilterItems[$_attributeCode])
55
+ ) {
56
+ foreach ($this->_selectedFilterItems[$_attributeCode] as $optionData) {
57
+ $this->getLayer()->getState()->addFilter(
58
+ $this->_createItem($optionData)
59
+ );
60
+ }
61
+ }
62
+
63
+ return $this;
64
+ }
65
+
66
+
67
+ /**
68
+ * Create filter item object
69
+ *
70
+ * @param array $data
71
+ * @param string $value
72
+ * @param int $count
73
+ *
74
+ * @return Mage_Catalog_Model_Layer_Filter_Item
75
+ */
76
+ protected function _createItem($data, $value = '', $count = 0)
77
+ {
78
+ $item = Mage::getModel('factfinder_asn/layer_filter_item')
79
+ ->setFilter($this);
80
+
81
+ foreach ($data as $key => $value) {
82
+ $method = 'set' . ucwords($key);
83
+ $item->$method($value);
84
+ }
85
+
86
+ return $item;
87
+ }
88
+
89
+
90
+ /**
91
+ * Get data array for building attribute filter items
92
+ *
93
+ * @return array
94
+ */
95
+ protected function _getItemsData()
96
+ {
97
+ if ($this->_filterItems === null) {
98
+ $attribute = $this->getAttributeModel();
99
+ $this->_requestVar = 'filter' . $attribute->getAttributeCode();
100
+
101
+ $options = $attribute->getItems();
102
+ $this->_filterItems = array();
103
+ if (is_array($options)) {
104
+ foreach ($options as $option) {
105
+ if ($option['selected'] == true) {
106
+ $this->_selectedFilterItems[$attribute->getAttributeCode()][] = $option;
107
+ continue;
108
+ }
109
+
110
+ $this->_filterItems[] = $option;
111
+ }
112
+ }
113
+ }
114
+
115
+ return $this->_filterItems;
116
+ }
117
+
118
+
119
+ /**
120
+ * Initialize filter items
121
+ *
122
+ * @return Mage_Catalog_Model_Layer_Filter_Abstract
123
+ */
124
+ protected function _initItems()
125
+ {
126
+ $data = $this->_getItemsData();
127
+ $items = array();
128
+ foreach ($data as $itemData) {
129
+ $items[] = $this->_createItem($itemData);
130
+ }
131
+
132
+ $this->_items = $items;
133
+
134
+ return $this;
135
+ }
136
+
137
+
138
+ }
app/code/community/FACTFinder/Asn/Model/Layer/Filter/Item.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Layer_Filter_Item
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Asn
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Asn_Model_Layer_Filter_Item extends Mage_Catalog_Model_Layer_Filter_Item
24
+ {
25
+
26
+
27
+ /**
28
+ * Get url for remove item from filter
29
+ *
30
+ * @return string
31
+ */
32
+ public function getRemoveUrl()
33
+ {
34
+ $params['_use_rewrite'] = true;
35
+ $params['_query'] = $this->getQueryParams();
36
+ $params['_escape'] = true;
37
+
38
+ if ($this->getSeoPath() && $this->_isOnSearchPage()) {
39
+ $query['q'] = null;
40
+ $params['_direct'] = 's' . $this->getSeoPath();
41
+ }
42
+
43
+ $url = Mage::getUrl('*/*/*', $params);
44
+
45
+ // fix by PHP_QUERY_RFC1738 encoded spaces
46
+ $url = str_replace('+', '%20', $url);
47
+
48
+ return $url;
49
+ }
50
+
51
+
52
+ /**
53
+ * Get url for remove whole filter
54
+ *
55
+ * @return string
56
+ */
57
+ public function getRemoveFilterUrl()
58
+ {
59
+ $params['_use_rewrite'] = true;
60
+ $params['_query'] = $this->getQueryParams();
61
+ $params['_escape'] = true;
62
+
63
+ unset($params['_query'][$this->getRequestVar()]);
64
+
65
+ if ($this->getSeoPath() && $this->_isOnSearchPage()) {
66
+ $query['q'] = null;
67
+ $params['_direct'] = 's' . $this->getSeoPath();
68
+ }
69
+
70
+ return Mage::getUrl('*/*/*', $params);
71
+ }
72
+
73
+
74
+ /**
75
+ * Get filter item url
76
+ *
77
+ * @return string
78
+ */
79
+ public function getUrl()
80
+ {
81
+ $query = array(
82
+ Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
83
+ );
84
+
85
+ $query = array_merge(
86
+ $query,
87
+ $this->getQueryParams()
88
+ );
89
+
90
+ if ($this->getSeoPath() && $this->_isOnSearchPage()) {
91
+ if ($query['q'] != '*') {
92
+ $query['q'] = null;
93
+ }
94
+
95
+ $url = Mage::getUrl('*/*/*', array('_query' => $query, '_direct' => 's' . $this->getSeoPath()));
96
+ } else {
97
+ $url = Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_query' => $query));
98
+ }
99
+
100
+ // fix PHP_QUERY_RFC1738 encoded spaces
101
+ $url = str_replace('+', '%20', $url);
102
+
103
+ return $url;
104
+ }
105
+
106
+
107
+ /**
108
+ * Check if we're on search page
109
+ *
110
+ * @return bool
111
+ */
112
+ protected function _isOnSearchPage()
113
+ {
114
+ return Mage::helper('factfinder/search')->getIsOnSearchPage();
115
+ }
116
+
117
+
118
+ }
app/code/community/FACTFinder/Asn/Model/Observer.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Observer
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Asn
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Asn_Model_Observer
24
+ {
25
+
26
+
27
+ /**
28
+ * Add layerd navigation filters on current layer block
29
+ *
30
+ * @param Mage_Catalog_Block_Layer_View $block
31
+ *
32
+ * @return $this
33
+ */
34
+ protected function _addLayeredNavigation($block)
35
+ {
36
+ $stateBlock = $block->getLayout()->createBlock('catalog/layer_state')
37
+ ->setLayer($block->getLayer());
38
+
39
+ $block->setChild('layer_state', $stateBlock);
40
+
41
+ $filterableAttributes = Mage::getResourceModel('factfinder_asn/product_attribute_collection');
42
+ foreach ($filterableAttributes as $index => $attribute) {
43
+ $filter = $block->getLayout()
44
+ ->createBlock('factfinder_asn/catalog_layer_factfinder')
45
+ ->setAttributeModel($attribute)
46
+ ->setLayer($block->getLayer())
47
+ ->init();
48
+
49
+ $block->setChild($attribute->getAttributeCode() . '_filter', $filter);
50
+
51
+ // remove category filter - it's enough to add it as a child
52
+ if ($attribute->getAttributeCode() == 'category') {
53
+ $filterableAttributes->removeItemByKey($index);
54
+ }
55
+ }
56
+
57
+ $block->setData('_filterable_attributes', $filterableAttributes);
58
+
59
+ return $this;
60
+ }
61
+
62
+
63
+ /**
64
+ * Add factfinder navigation on catalog
65
+ *
66
+ * @param Varian_Object $observer
67
+ *
68
+ * @return void
69
+ */
70
+ public function addLayerFiltersToCatalog($observer)
71
+ {
72
+ if (!Mage::helper('factfinder')->isEnabled('catalog_navigation')) {
73
+ return;
74
+ }
75
+
76
+ $block = $observer->getBlock();
77
+
78
+ if (!$block instanceof Mage_Catalog_Block_Layer_View
79
+ || $block instanceof Mage_CatalogSearch_Block_Layer
80
+ ) {
81
+ return;
82
+ }
83
+
84
+ $this->_addLayeredNavigation($block);
85
+ }
86
+
87
+
88
+ /**
89
+ * Add factfinder navigation on search page
90
+ *
91
+ * @param Varien_Object $observer
92
+ *
93
+ * @return void
94
+ */
95
+ public function addLayerFiltersToSearch($observer)
96
+ {
97
+ $block = $observer->getBlock();
98
+
99
+ if (!$block instanceof Mage_CatalogSearch_Block_Layer
100
+ || !Mage::helper('factfinder')->isEnabled('asn')
101
+ ) {
102
+ return;
103
+ }
104
+
105
+ $this->_addLayeredNavigation($block);
106
+ }
107
+
108
+
109
+ /**
110
+ * Reset current search layer for further use in the block
111
+ *
112
+ * @param Varien_Object $observer
113
+ *
114
+ * @return void
115
+ */
116
+ public function resetCurrentCatalogLayer($observer)
117
+ {
118
+ if (!Mage::helper('factfinder')->isEnabled('catalog_navigation')) {
119
+ return;
120
+ }
121
+
122
+ Mage::register('current_layer', Mage::getSingleton('factfinder_asn/catalog_layer'));
123
+ }
124
+
125
+
126
+ }
app/code/community/FACTFinder/Asn/Model/Resource/Product/Attribute/Collection.php ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Resource_Product_Attribute_Collection
15
+ *
16
+ * Filter Attribute Collection
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Asn
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Asn_Model_Resource_Product_Attribute_Collection
26
+ extends Mage_Catalog_Model_Resource_Product_Attribute_Collection
27
+ {
28
+
29
+ /**
30
+ * @var array|null
31
+ */
32
+ protected $_attributeLabels = null;
33
+
34
+ /**
35
+ * @var int|null
36
+ */
37
+ protected $_storeId = null;
38
+
39
+
40
+ /**
41
+ * Get collection size
42
+ *
43
+ * @return int
44
+ */
45
+ public function getSize()
46
+ {
47
+ return count($this->_getSearchHandler()->getAfterSearchNavigation());
48
+ }
49
+
50
+
51
+ /**
52
+ * Get search handler
53
+ *
54
+ * @return FACTFinder_Asn_Model_Handler_Search
55
+ */
56
+ protected function _getSearchHandler()
57
+ {
58
+ return Mage::getSingleton('factfinder_asn/handler_search');
59
+ }
60
+
61
+
62
+ /**
63
+ * Load entities records into items
64
+ *
65
+ * @param bool $printQuery
66
+ * @param bool $logQuery
67
+ *
68
+ * @return FACTFinder_Asn_Model_Resource_Product_Attribute_Collection
69
+ */
70
+ public function load($printQuery = false, $logQuery = false)
71
+ {
72
+ if ($this->isLoaded()) {
73
+ return $this;
74
+ }
75
+
76
+ $result = $this->_getSearchHandler()->getAfterSearchNavigation();
77
+
78
+ if (count($result)) {
79
+ $this->resetData();
80
+
81
+ foreach ($result as $row) {
82
+ $item = $this->getNewEmptyItem();
83
+ if ($this->getIdFieldName()) {
84
+ $item->setIdFieldName($this->getIdFieldName());
85
+ }
86
+
87
+ $row['store_label'] = $this->_getStoreLabelsByAttributeCode($row['name']);
88
+ $item->addData($row);
89
+ $item->setAttributeCode(strtolower($item->getAttributeCode()));
90
+ $this->addItem($item);
91
+ }
92
+
93
+ $this->_setIsLoaded();
94
+ $this->_afterLoad();
95
+ }
96
+
97
+ return $this;
98
+ }
99
+
100
+
101
+ /**
102
+ * Add search query filter
103
+ *
104
+ * @param Mage_CatalogSearch_Model_Query $query
105
+ *
106
+ * @return Mage_CatalogSearch_Model_Mysql4_Search_Collection
107
+ */
108
+ public function addSearchFilter($query)
109
+ {
110
+ return $this;
111
+ }
112
+
113
+
114
+ /**
115
+ * Retrieve store labels by given attribute code
116
+ *
117
+ * @param string $attributeCode
118
+ *
119
+ * @return array|string
120
+ */
121
+ protected function _getStoreLabelsByAttributeCode($attributeCode)
122
+ {
123
+ if ($this->_attributeLabels === null) {
124
+ $entityType = Mage::getSingleton('eav/config')->getEntityType('catalog_product');
125
+
126
+ $select = $this->getConnection()->select()
127
+ ->from(array('main_table' => $this->getTable('eav/attribute')), array('attribute_code'))
128
+ ->joinLeft(
129
+ array('additional_table' => $this->getTable('eav/attribute_label')),
130
+ 'additional_table.attribute_id = main_table.attribute_id',
131
+ null
132
+ )
133
+ ->columns(array(
134
+ 'value' => new Zend_Db_Expr(
135
+ 'IF(additional_table.value IS NULL, main_table.frontend_label, additional_table.value)'
136
+ )
137
+ ))
138
+ ->where('main_table.entity_type_id = ?', $entityType->getEntityTypeId())
139
+ ->where('additional_table.store_id IS NULL OR additional_table.store_id=?', $this->_storeId);
140
+
141
+ $this->_attributeLabels = $this->getConnection()->fetchPairs($select);
142
+ }
143
+
144
+ if (!isset($this->_attributeLabels[$attributeCode])) {
145
+ return $attributeCode;
146
+ }
147
+
148
+ return $this->_attributeLabels[$attributeCode];
149
+ }
150
+
151
+
152
+ /**
153
+ * Set Store ID
154
+ *
155
+ * @param int $storeId
156
+ *
157
+ * @return FACTFinder_Asn_Model_Resource_Product_Attribute_Collection
158
+ */
159
+ public function setStoreId($storeId)
160
+ {
161
+ $this->_storeId = $storeId;
162
+
163
+ return $this;
164
+ }
165
+
166
+
167
+ /**
168
+ * Set Order field
169
+ *
170
+ * @param string $attribute
171
+ * @param string $dir
172
+ *
173
+ * @return FACTFinder_Asn_Model_Resource_Product_Attribute_Collection
174
+ */
175
+ public function setOrder($attribute, $dir = 'desc')
176
+ {
177
+ return $this;
178
+ }
179
+
180
+
181
+ }
app/code/community/FACTFinder/Asn/Model/Resource/Search/Collection.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Asn_Model_Resource_Search_Collection
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Asn
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Asn_Model_Resource_Search_Collection extends FACTFinder_Core_Model_Resource_Search_Collection
24
+ {
25
+
26
+
27
+ /**
28
+ * Get FACT-Finder Facade
29
+ *
30
+ * @return FACTFinder_Core_Model_Handler_Search
31
+ */
32
+ protected function _getSearchHandler()
33
+ {
34
+ return Mage::getSingleton('factfinder_asn/handler_search');
35
+ }
36
+
37
+
38
+ }
app/code/community/FACTFinder/Asn/etc/config.xml ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Asn
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Asn
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <config>
15
+ <modules>
16
+ <FACTFinder_Asn>
17
+ <version>4.0.1</version>
18
+ </FACTFinder_Asn>
19
+ </modules>
20
+ <global>
21
+ <models>
22
+ <factfinder_asn>
23
+ <class>FACTFinder_Asn_Model</class>
24
+ <resourceModel>factfinder_asn_resource</resourceModel>
25
+ </factfinder_asn>
26
+ <factfinder_asn_resource>
27
+ <class>FACTFinder_Asn_Model_Resource</class>
28
+ </factfinder_asn_resource>
29
+ </models>
30
+ <blocks>
31
+ <factfinder_asn>
32
+ <class>FACTFinder_Asn_Block</class>
33
+ </factfinder_asn>
34
+ <catalog>
35
+ <rewrite>
36
+ <layer_state>FACTFinder_Asn_Block_Catalog_Layer_State</layer_state>
37
+ </rewrite>
38
+ </catalog>
39
+ <catalogsearch>
40
+ <rewrite>
41
+ <layer_state>FACTFinder_Asn_Block_Catalog_Layer_State</layer_state>
42
+ </rewrite>
43
+ </catalogsearch>
44
+ </blocks>
45
+ <helpers>
46
+ <factfinder_asn>
47
+ <class>FACTFinder_Asn_Helper</class>
48
+ </factfinder_asn>
49
+ </helpers>
50
+ </global>
51
+ <frontend>
52
+ <events>
53
+ <core_block_abstract_prepare_layout_after>
54
+ <observers>
55
+ <factfinder_asn_add_layer_filters>
56
+ <class>factfinder_asn/observer</class>
57
+ <method>addLayerFiltersToSearch</method>
58
+ </factfinder_asn_add_layer_filters>
59
+ <factfinder_asn_add_layer_filters_catalog>
60
+ <class>factfinder_asn/observer</class>
61
+ <method>addLayerFiltersToCatalog</method>
62
+ </factfinder_asn_add_layer_filters_catalog>
63
+ </observers>
64
+ </core_block_abstract_prepare_layout_after>
65
+ <controller_action_predispatch_catalog_category_view>
66
+ <observers>
67
+ <factfinder_asn_reset_catalog_layer>
68
+ <class>factfinder_asn/observer</class>
69
+ <method>resetCurrentCatalogLayer</method>
70
+ </factfinder_asn_reset_catalog_layer>
71
+ </observers>
72
+ </controller_action_predispatch_catalog_category_view>
73
+ </events>
74
+ <layout>
75
+ <updates>
76
+ <factfinder_asn>
77
+ <file>factfinder/asn.xml</file>
78
+ </factfinder_asn>
79
+ </updates>
80
+ </layout>
81
+ </frontend>
82
+ </config>
app/code/community/FACTFinder/Asn/etc/system.xml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Asn
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Asn
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <config>
15
+ <sections>
16
+ <factfinder>
17
+ <groups>
18
+ <modules>
19
+ <fields>
20
+ <catalog_navigation>
21
+ <label>Replace Catalog Navigation</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>15</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </catalog_navigation>
29
+ </fields>
30
+ </modules>
31
+ </groups>
32
+ </factfinder>
33
+ </sections>
34
+ </config>
app/code/community/FACTFinder/Campaigns/Block/Abstract.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Abstract
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ abstract class FACTFinder_Campaigns_Block_Abstract extends Mage_Core_Block_Template
24
+ {
25
+
26
+ /**
27
+ * Handler used to get data from ff
28
+ *
29
+ * @var FACTFinder_Campaigns_Model_Handler_Cart
30
+ */
31
+ protected $_handlerModel = '';
32
+
33
+
34
+ /**
35
+ * Check if campaigns can be shown
36
+ *
37
+ * @return bool
38
+ */
39
+ protected function _canBeShown()
40
+ {
41
+ if (Mage::registry('current_category')
42
+ && !Mage::helper('factfinder_campaigns')->isCatalogNavigationReplaced()
43
+ ) {
44
+ return false;
45
+ }
46
+
47
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
48
+ }
49
+
50
+
51
+ /**
52
+ * Get handler singleton
53
+ *
54
+ * @return \Mage_Core_Model_Abstract
55
+ */
56
+ protected function _getHandler()
57
+ {
58
+ return Mage::getSingleton($this->_handlerModel);
59
+ }
60
+
61
+
62
+ /**
63
+ * Render html
64
+ * Return empty string if module isn't enabled
65
+ *
66
+ * @return string
67
+ */
68
+ protected function _toHtml()
69
+ {
70
+ if (!$this->_canBeShown()) {
71
+ return '';
72
+ }
73
+
74
+ return parent::_toHtml();
75
+ }
76
+
77
+
78
+ }
app/code/community/FACTFinder/Campaigns/Block/Advisory/Product.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Advisory_Product
15
+ *
16
+ * Provides advisory hints to the product view page
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Campaigns
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Campaigns_Block_Advisory_Product extends FACTFinder_Campaigns_Block_Abstract
26
+ {
27
+
28
+ /**
29
+ * @var string
30
+ */
31
+ protected $_handlerModel = 'factfinder_campaigns/handler_product';
32
+
33
+
34
+ /**
35
+ * @return \Mage_Core_Model_Abstract
36
+ */
37
+ protected function _getHandler()
38
+ {
39
+ return Mage::getSingleton('factfinder_campaigns/handler_product', $this->_getProductIds());
40
+ }
41
+
42
+
43
+ /**
44
+ * @return array
45
+ */
46
+ protected function _getProductIds()
47
+ {
48
+ $productIds = array();
49
+ if (Mage::registry('current_product')) {
50
+ $productIds = array(
51
+ Mage::registry('current_product')->getData(Mage::helper('factfinder_campaigns')->getIdFieldName())
52
+ );
53
+ }
54
+
55
+ return $productIds;
56
+ }
57
+
58
+
59
+ /**
60
+ * Get campaign questions and answers
61
+ *
62
+ * @return array
63
+ */
64
+ public function getActiveQuestions()
65
+ {
66
+ $questions = array();
67
+
68
+ if ($this->canCampaignBeDisplay()) {
69
+ $questions = $this->_getHandler()->getActiveAdvisorQuestions();
70
+ }
71
+
72
+ return $questions;
73
+ }
74
+
75
+
76
+ /**
77
+ * Check if campaign can be displayed
78
+ *
79
+ * @return bool
80
+ */
81
+ protected function canCampaignBeDisplay()
82
+ {
83
+ return (bool) Mage::registry('current_product');
84
+ }
85
+
86
+
87
+ }
app/code/community/FACTFinder/Campaigns/Block/Advisory/Search.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Advisory_Search
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Advisory_Search extends FACTFinder_Campaigns_Block_Abstract
24
+ {
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected $_handlerModel = 'factfinder_campaigns/handler_search';
30
+
31
+
32
+ /**
33
+ * Get Campaign Text
34
+ *
35
+ * @return array
36
+ */
37
+ public function getActiveQuestions()
38
+ {
39
+ $questions = array();
40
+
41
+ $_campaigns = $this->_getHandler()->getCampaigns();
42
+ if ($_campaigns && $_campaigns->hasActiveQuestions()) {
43
+ $questions = $_campaigns->getActiveQuestions();
44
+ }
45
+
46
+ return $questions;
47
+ }
48
+
49
+
50
+ }
app/code/community/FACTFinder/Campaigns/Block/Feedback/Abstract.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Feedback_Abstract
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ abstract class FACTFinder_Campaigns_Block_Feedback_Abstract extends FACTFinder_Campaigns_Block_Abstract
24
+ {
25
+
26
+ protected $_template = 'factfinder/campaigns/feedback.phtml';
27
+
28
+
29
+ /**
30
+ * Get campaign feedback based on label
31
+ *
32
+ * @return array
33
+ */
34
+ public function getActiveFeedback()
35
+ {
36
+ $feedback = '';
37
+
38
+ $_campaigns = $this->_getHandler()->getCampaigns();
39
+
40
+ if ($_campaigns && $_campaigns->hasFeedback()) {
41
+ $label = $this->getLabel();
42
+ $feedback = $_campaigns->getFeedback($label);
43
+ }
44
+
45
+ return $feedback;
46
+ }
47
+
48
+
49
+ }
app/code/community/FACTFinder/Campaigns/Block/Feedback/Cart.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Feedback_Cart
15
+ *
16
+ * Provides feedback text to the cart page
17
+ *
18
+ * @category Mage
19
+ * @package FACTFinder_Campaigns
20
+ * @author Flagbit Magento Team <magento@flagbit.de>
21
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
22
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
23
+ * @link http://www.flagbit.de
24
+ */
25
+ class FACTFinder_Campaigns_Block_Feedback_Cart extends FACTFinder_Campaigns_Block_Feedback_Abstract
26
+ {
27
+
28
+ protected $_handlerModel = 'factfinder_campaigns/handler_cart';
29
+
30
+ }
app/code/community/FACTFinder/Campaigns/Block/Feedback/Product.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Feedback_Product
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Feedback_Product extends FACTFinder_Campaigns_Block_Feedback_Abstract
24
+ {
25
+
26
+ protected $_handlerModel = 'factfinder_campaigns/handler_product';
27
+
28
+
29
+ /**
30
+ * Check is the campign can be shown on product page
31
+ *
32
+ * @return bool
33
+ */
34
+ protected function _canBeShown()
35
+ {
36
+ $enabledOnProduct = Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct();
37
+
38
+ return parent::_canBeShown() && $enabledOnProduct;
39
+ }
40
+
41
+
42
+ }
app/code/community/FACTFinder/Campaigns/Block/Feedback/Search.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Feedback_Search
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Feedback_Search extends FACTFinder_Campaigns_Block_Feedback_Abstract
24
+ {
25
+
26
+ protected $_handlerModel = 'factfinder_campaigns/handler_search';
27
+ }
app/code/community/FACTFinder/Campaigns/Block/Pushed/Abstract.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Pushed_Abstract
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ abstract class FACTFinder_Campaigns_Block_Pushed_Abstract extends Mage_Catalog_Block_Product_List_Upsell
24
+ {
25
+ const HEADER_LABEL = 'pushed products header';
26
+
27
+ protected $_template = 'factfinder/campaigns/pushed.phtml';
28
+
29
+ /**
30
+ * Handler model to use
31
+ * Must be redefined in descendants
32
+ *
33
+ * @var string
34
+ */
35
+ protected $_handlerModel = '';
36
+
37
+
38
+ /**
39
+ * Get handler singleton
40
+ *
41
+ * @return \Mage_Core_Model_Abstract
42
+ */
43
+ protected function _getHandler()
44
+ {
45
+ return Mage::getSingleton($this->_handlerModel);
46
+ }
47
+
48
+
49
+ /**
50
+ * Prepare collection data
51
+ *
52
+ * @return FACTFinder_Campaigns_Block_Pushed_Abstract
53
+ */
54
+ protected function _prepareData()
55
+ {
56
+ $this->getItemCollection()
57
+ ->addAttributeToSelect('name')
58
+ ->addAttributeToSelect('small_image')
59
+ ->addAttributeToSelect('thumbnail')
60
+ ->addPriceData();
61
+
62
+ return $this;
63
+ }
64
+
65
+
66
+ /**
67
+ * Get pushed products collection
68
+ *
69
+ * @return FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
70
+ */
71
+ public function getItemCollection()
72
+ {
73
+ if ($this->_itemCollection === null) {
74
+ $this->_itemCollection = Mage::getResourceModel('factfinder_campaigns/pushedproducts_collection');
75
+ $this->_itemCollection->setHandler($this->_getHandler());
76
+ }
77
+
78
+ return $this->_itemCollection;
79
+ }
80
+
81
+
82
+ /**
83
+ * Get feedback header text
84
+ *
85
+ * @return string
86
+ */
87
+ public function getHeader()
88
+ {
89
+ $campaigns = $this->_getHandler()->getCampaigns();
90
+
91
+ $label = $campaigns->getFeedback(self::HEADER_LABEL);
92
+
93
+ if (!empty($label)) {
94
+ return $label;
95
+ }
96
+
97
+ return $this->__('Pushed products');
98
+ }
99
+
100
+
101
+ /**
102
+ * Check if campaigns can be shown
103
+ *
104
+ * @return bool
105
+ */
106
+ protected function _canBeShown()
107
+ {
108
+ return (bool) Mage::helper('factfinder')->isEnabled('campaigns');
109
+ }
110
+
111
+
112
+ /**
113
+ * Render html
114
+ * Return empty string if module isn't enabled
115
+ *
116
+ * @return string
117
+ */
118
+ protected function _toHtml()
119
+ {
120
+ if (!$this->_canBeShown()) {
121
+ return '';
122
+ }
123
+
124
+ return parent::_toHtml();
125
+ }
126
+
127
+
128
+ }
app/code/community/FACTFinder/Campaigns/Block/Pushed/Cart.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Cart_Pushed
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Pushed_Cart extends FACTFinder_Campaigns_Block_Pushed_Abstract
24
+ {
25
+
26
+ protected $_handlerModel = 'factfinder_campaigns/handler_cart';
27
+
28
+ }
app/code/community/FACTFinder/Campaigns/Block/Pushed/Product.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Pushed_Product
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Pushed_Product extends FACTFinder_Campaigns_Block_Pushed_Abstract
24
+ {
25
+
26
+ protected $_handlerModel = 'factfinder_campaigns/handler_product';
27
+
28
+
29
+ /**
30
+ * Check is the campign can be shown on product page
31
+ *
32
+ * @return bool
33
+ */
34
+ protected function _canBeShown()
35
+ {
36
+ $enabledOnProduct = Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct();
37
+
38
+ return parent::_canBeShown() && $enabledOnProduct;
39
+ }
40
+
41
+
42
+ }
app/code/community/FACTFinder/Campaigns/Block/Pushed/Search.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Block_Search_Pushed
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Block_Pushed_Search extends FACTFinder_Campaigns_Block_Pushed_Abstract
24
+ {
25
+
26
+ protected $_handlerModel = 'factfinder_campaigns/handler_search';
27
+
28
+
29
+ /**
30
+ * Check if campaigns can be shown
31
+ *
32
+ * @return bool
33
+ */
34
+ protected function _canBeShown()
35
+ {
36
+ if (Mage::registry('current_category')
37
+ && !Mage::helper('factfinder_campaigns')->isCatalogNavigationReplaced()
38
+ ) {
39
+ return false;
40
+ }
41
+
42
+ return parent::_canBeShown();
43
+ }
44
+
45
+
46
+ }
app/code/community/FACTFinder/Campaigns/Helper/Data.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Helper_Data
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Helper_Data extends Mage_Core_Helper_Abstract
24
+ {
25
+ const CATALOG_NAVIGATION_REPLACED_CONFIG_PATH = 'factfinder/modules/catalog_navigation';
26
+ const CAMPAIGNS_IDENTIFIER_CONFIG_PATH = 'factfinder/config/campaigns_identifier';
27
+ const ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH = 'factfinder/config/enable_campaigns_on_prod_page';
28
+
29
+
30
+ /**
31
+ * Check config if showing campaigns on product page is enabled
32
+ *
33
+ * @return bool
34
+ */
35
+ public function canShowCampaignsOnProduct()
36
+ {
37
+ return (bool) Mage::app()->getStore()->getConfig(self::ENABLE_CAMPAIGNS_ON_PROD_PAGE_CONFIG_PATH);
38
+ }
39
+
40
+
41
+ /**
42
+ * Get id field name for campaigns
43
+ *
44
+ * @return bool
45
+ */
46
+ public function getIdFieldName()
47
+ {
48
+ return Mage::getStoreConfig(self::CAMPAIGNS_IDENTIFIER_CONFIG_PATH);
49
+ }
50
+
51
+
52
+ /**
53
+ * Check is catalog navigation replacement is enabled
54
+ *
55
+ * @return bool
56
+ */
57
+ public function isCatalogNavigationReplaced()
58
+ {
59
+ return (bool) Mage::app()->getStore()->getConfig(self::CATALOG_NAVIGATION_REPLACED_CONFIG_PATH);
60
+ }
61
+
62
+
63
+ }
app/code/community/FACTFinder/Campaigns/Model/Facade.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Facade
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Facade extends FACTFinder_Core_Model_Facade
24
+ {
25
+
26
+
27
+ /**
28
+ * Get product campaign adapter instance
29
+ *
30
+ * @param string $channel
31
+ *
32
+ * @return \FACTFinder\Adapter\AbstractAdapter
33
+ */
34
+ public function getProductCampaignAdapter($channel = null)
35
+ {
36
+ return $this->_getAdapter("productCampaign", $channel);
37
+ }
38
+
39
+
40
+ /**
41
+ * Set config params to product campaign adapter
42
+ *
43
+ * @param array $params
44
+ * @param string $channel
45
+ * @param int $id
46
+ */
47
+ public function configureProductCampaignAdapter($params, $channel = null, $id = null)
48
+ {
49
+ $this->_configureAdapter($params, "productCampaign", $channel, $id);
50
+ }
51
+
52
+
53
+ /**
54
+ * Get available product campaigns for the current adapter configuration
55
+ *
56
+ * @param string $channel
57
+ * @param int $id
58
+ *
59
+ * @return Object
60
+ */
61
+ public function getProductCampaigns($channel = null, $id = null)
62
+ {
63
+ return $this->_getFactFinderObject("productCampaign", "getCampaigns", $channel, $id);
64
+ }
65
+
66
+
67
+ }
app/code/community/FACTFinder/Campaigns/Model/Handler/Abstract.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Handler_Abstract
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ abstract class FACTFinder_Campaigns_Model_Handler_Abstract extends FACTFinder_Core_Model_Handler_Search
24
+ {
25
+ /**
26
+ * Model used as facade
27
+ *
28
+ * @var string
29
+ */
30
+ protected $_facadeModel = 'factfinder_campaigns/facade';
31
+
32
+ /**
33
+ * Product IDs
34
+ *
35
+ * @var array
36
+ */
37
+ protected $_productIds = array();
38
+
39
+ /**
40
+ * Available campaigns
41
+ *
42
+ * @var array|null
43
+ */
44
+ protected $_campaigns = null;
45
+
46
+
47
+ /**
48
+ * Flag of feature availability
49
+ *
50
+ * @var bool
51
+ */
52
+ protected $_featureAvailable = true;
53
+
54
+
55
+ /**
56
+ * Class constructor
57
+ *
58
+ * @param array $productIds
59
+ */
60
+ public function __construct($productIds)
61
+ {
62
+ $this->_productIds = $productIds;
63
+ parent::__construct();
64
+ }
65
+
66
+
67
+ /**
68
+ * Retrieve redirect url from campaign
69
+ *
70
+ * @return string
71
+ */
72
+ public function getRedirect()
73
+ {
74
+ $url = null;
75
+ $campaigns = $this->getCampaigns();
76
+
77
+ if (!empty($campaigns) && $campaigns->hasRedirect()) {
78
+ $url = $campaigns->getRedirectUrl();
79
+ }
80
+
81
+ return $url;
82
+ }
83
+
84
+
85
+ /**
86
+ * Configure all facade settings
87
+ */
88
+ protected function _configureFacade()
89
+ {
90
+ $params = array();
91
+
92
+ $params['do'] = $this->_getDoParam();
93
+ $params['productNumber'] = $this->_getProductNumberParam();
94
+ $params['idsOnly'] = 'true';
95
+
96
+ $this->_getFacade()->configureProductCampaignAdapter($params);
97
+ }
98
+
99
+
100
+ /**
101
+ * Get name of the method to be executed in the adapter
102
+ *
103
+ * @return string
104
+ */
105
+ abstract protected function _getDoParam();
106
+
107
+
108
+ /**
109
+ * Get array of product ids
110
+ *
111
+ * @return array
112
+ */
113
+ abstract protected function _getProductNumberParam();
114
+
115
+
116
+ /**
117
+ * Get array of guestions from advisor campaign
118
+ *
119
+ * @return array
120
+ */
121
+ public function getActiveAdvisorQuestions()
122
+ {
123
+ $campaigns = $this->getCampaigns();
124
+
125
+ $questions = array();
126
+
127
+ if ($campaigns && $campaigns->hasActiveQuestions()) {
128
+ $questions = $campaigns->getActiveQuestions();
129
+ }
130
+
131
+ return $questions;
132
+ }
133
+
134
+
135
+ /**
136
+ * Get array of campaigns available
137
+ *
138
+ * @return array
139
+ */
140
+ public function getCampaigns()
141
+ {
142
+ if ($this->_featureAvailable && $this->_campaigns === null) {
143
+ $this->_campaigns = $this->_getFacade()->getProductCampaigns();
144
+ }
145
+
146
+ // it's still null (disabled or en error happened)
147
+ if ($this->_campaigns === null) {
148
+ $this->_campaigns = array();
149
+ }
150
+
151
+ return $this->_campaigns;
152
+ }
153
+
154
+
155
+ }
app/code/community/FACTFinder/Campaigns/Model/Handler/Cart.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Handler_Cart
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Handler_Cart extends FACTFinder_Campaigns_Model_Handler_Abstract
24
+ {
25
+
26
+ /**
27
+ * Get name of the method to be executed in the adapter
28
+ *
29
+ * @return string
30
+ */
31
+ protected function _getDoParam()
32
+ {
33
+ return 'getShoppingCartCampaigns';
34
+ }
35
+
36
+
37
+ /**
38
+ * Get array of product ids
39
+ *
40
+ * @return array
41
+ */
42
+ protected function _getProductNumberParam()
43
+ {
44
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
45
+
46
+ $productIds = array();
47
+
48
+ /** @var Mage_Sales_Model_Quote_Item $item */
49
+ foreach ($quote->getAllItems() as $item) {
50
+ $productIds[] = $item->getProduct()->getData(Mage::helper('factfinder_campaigns')->getIdFieldName());
51
+ }
52
+
53
+ return $productIds;
54
+ }
55
+
56
+
57
+ /**
58
+ * Get array of campaigns available
59
+ *
60
+ * @return array
61
+ */
62
+ public function getCampaigns()
63
+ {
64
+ $this->_getFacade()->getProductCampaignAdapter()->makeShoppingCartCampaign();
65
+
66
+ return parent::getCampaigns();
67
+ }
68
+
69
+
70
+ }
app/code/community/FACTFinder/Campaigns/Model/Handler/Product.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Handler_Product
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Handler_Product extends FACTFinder_Campaigns_Model_Handler_Abstract
24
+ {
25
+
26
+ /**
27
+ * Get name of the method to be executed in the adapter
28
+ *
29
+ * @return string
30
+ */
31
+ protected function _getDoParam()
32
+ {
33
+ return 'getProductCampaigns';
34
+ }
35
+
36
+
37
+ /**
38
+ * Get array of product ids
39
+ *
40
+ * @return array
41
+ */
42
+ protected function _getProductNumberParam()
43
+ {
44
+ if (is_array($this->_productIds)) {
45
+ return current($this->_productIds);
46
+ } else {
47
+ return $this->_productIds;
48
+ }
49
+ }
50
+
51
+
52
+ /**
53
+ * Get array of campaigns available
54
+ *
55
+ * @return array
56
+ */
57
+ public function getCampaigns()
58
+ {
59
+ $this->_getFacade()->getProductCampaignAdapter()->makeProductCampaign();
60
+
61
+ return parent::getCampaigns();
62
+ }
63
+
64
+
65
+ }
app/code/community/FACTFinder/Campaigns/Model/Handler/Search.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Handler_Search
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Handler_Search extends FACTFinder_Core_Model_Handler_Search
24
+ {
25
+
26
+ /**
27
+ * Array of ff campaigns
28
+ *
29
+ * @var array
30
+ */
31
+ protected $_campaigns;
32
+
33
+
34
+ /**
35
+ * Retrieve redirect url from campaign
36
+ *
37
+ * @return string
38
+ */
39
+ public function getRedirect()
40
+ {
41
+ $url = null;
42
+ $campaigns = $this->getCampaigns();
43
+
44
+ if (!empty($campaigns) && $campaigns->hasRedirect()) {
45
+ $url = $campaigns->getRedirectUrl();
46
+ }
47
+
48
+ return $url;
49
+ }
50
+
51
+
52
+ /**
53
+ * Get array of campaigns available
54
+ *
55
+ * @return array
56
+ */
57
+ public function getCampaigns()
58
+ {
59
+ if ($this->_campaigns === null) {
60
+ $this->_campaigns = $this->_getFacade()->getSearchCampaigns();
61
+ }
62
+
63
+ if ($this->_campaigns === null) {
64
+ $this->_campaigns = array();
65
+ }
66
+
67
+ return $this->_campaigns;
68
+ }
69
+
70
+
71
+ }
app/code/community/FACTFinder/Campaigns/Model/Observer.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Observer
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Observer
24
+ {
25
+
26
+
27
+ /**
28
+ * Handles campaign redirects on
29
+ * controller_action_layout_generate_blocks_after
30
+ *
31
+ * @param Varien_Object $observer
32
+ */
33
+ public function handleCampaignsRedirect($observer)
34
+ {
35
+ if (!Mage::helper('factfinder')->isEnabled('campaigns')
36
+ || (Mage::registry('current_product') && !Mage::helper('factfinder_campaigns')->canShowCampaignsOnProduct())
37
+ ) {
38
+ return;
39
+ }
40
+
41
+ if (!Mage::registry('current_layer') && !Mage::registry('current_product')) {
42
+ return;
43
+ }
44
+
45
+ if (Mage::registry('current_product')) {
46
+ $product = Mage::registry('current_product');
47
+ $ids = array($product->getData(Mage::helper('factfinder_campaigns')->getIdFieldName()));
48
+ $handler = Mage::getModel('factfinder_campaigns/handler_product', $ids);
49
+ } elseif (Mage::helper('factfinder/search')->getIsOnSearchPage()) {
50
+ $handler = Mage::getSingleton('factfinder_campaigns/handler_search');
51
+ } else {
52
+ return;
53
+ }
54
+
55
+ $redirect = $handler->getRedirect();
56
+
57
+ if ($redirect) {
58
+ // handle relative urls
59
+ if (!Zend_Uri::check($redirect)) {
60
+ $redirect = Mage::getBaseUrl() . $redirect;
61
+ }
62
+
63
+ $response = Mage::app()->getResponse();
64
+ $response->setRedirect($redirect);
65
+ $response->sendResponse();
66
+ exit;
67
+ }
68
+ }
69
+
70
+
71
+ }
app/code/community/FACTFinder/Campaigns/Model/Resource/Pushedproducts/Collection.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+
13
+ /**
14
+ * Class FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
15
+ *
16
+ * @category Mage
17
+ * @package FACTFinder_Campaigns
18
+ * @author Flagbit Magento Team <magento@flagbit.de>
19
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ * @link http://www.flagbit.de
22
+ */
23
+ class FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
24
+ extends Mage_Catalog_Model_Resource_Product_Collection
25
+ {
26
+
27
+ /**
28
+ * Handler model to process requests
29
+ *
30
+ * @var string
31
+ */
32
+ protected $_handler;
33
+
34
+
35
+ /**
36
+ * Initialization of the handler
37
+ */
38
+ protected function _construct()
39
+ {
40
+ $this->_handler = Mage::getSingleton('factfinder_campaigns/handler_search');
41
+
42
+ parent::_construct();
43
+ }
44
+
45
+
46
+ /**
47
+ * Set handler model
48
+ *
49
+ * @param $handler
50
+ *
51
+ * @return FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
52
+ */
53
+ public function setHandler($handler)
54
+ {
55
+ $this->_handler = $handler;
56
+
57
+ return $this;
58
+ }
59
+
60
+
61
+ /**
62
+ * Get collection size
63
+ *
64
+ * @return int
65
+ */
66
+ public function getSize()
67
+ {
68
+ return count($this->_getCampaigns()->getPushedProducts());
69
+ }
70
+
71
+
72
+ /**
73
+ * Get campaigns
74
+ *
75
+ * @return FACTFinder\Data\Campaign
76
+ */
77
+ protected function _getCampaigns()
78
+ {
79
+ return $this->_handler->getCampaigns();
80
+ }
81
+
82
+
83
+ /**
84
+ * Load entities records into items
85
+ *
86
+ * @param bool $printQuery
87
+ * @param bool $logQuery
88
+ *
89
+ * @throws Exception
90
+ *
91
+ * @return FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
92
+ */
93
+ public function _loadEntities($printQuery = false, $logQuery = false)
94
+ {
95
+
96
+ $productIds = array();
97
+ $campaigns = $this->_getCampaigns();
98
+
99
+ if (!$campaigns) {
100
+ return $this;
101
+ }
102
+
103
+ foreach ($campaigns->getPushedProducts() as $record) {
104
+ $productIds[$record->getId()] = new Varien_Object(
105
+ array(
106
+ 'similarity' => $record->getSimilarity(),
107
+ 'position' => $record->getPosition(),
108
+ )
109
+ );
110
+ }
111
+
112
+ $idFieldName = Mage::helper('factfinder_campaigns')->getIdFieldName();
113
+
114
+ if (!empty($productIds)) {
115
+ // add Filter to Query
116
+ $this->addFieldToFilter(
117
+ $idFieldName,
118
+ array('in' => array_keys($productIds))
119
+ );
120
+
121
+ $this->_pageSize = null;
122
+
123
+ $this->getSelect()->reset(Zend_Db_Select::LIMIT_COUNT);
124
+ $this->getSelect()->reset(Zend_Db_Select::LIMIT_OFFSET);
125
+
126
+ $this->printLogQuery($printQuery, $logQuery);
127
+ Mage::helper('factfinder/debug')->log('Search SQL Query: ' . $this->getSelect()->__toString());
128
+
129
+ try {
130
+ $rows = $this->_fetchAll($this->getSelect());
131
+ } catch (Exception $e) {
132
+ Mage::printException($e, $this->getSelect());
133
+ $this->printLogQuery(true, true, $this->getSelect());
134
+ throw $e;
135
+ }
136
+
137
+ $items = array();
138
+ foreach ($rows as $v) {
139
+ $items[$v[$idFieldName]] = $v;
140
+ }
141
+
142
+ foreach ($productIds as $productId => $additionalData) {
143
+ if (empty($items[$productId])) {
144
+ continue;
145
+ }
146
+
147
+ $v = array_merge($items[$productId], $additionalData->toArray());
148
+ $object = $this->getNewEmptyItem()->setData($v);
149
+
150
+ $this->addItem($object);
151
+ if (isset($this->_itemsById[$object->getId()])) {
152
+ $this->_itemsById[$object->getId()][] = $object;
153
+ } else {
154
+ $this->_itemsById[$object->getId()] = array($object);
155
+ }
156
+ }
157
+
158
+ }
159
+
160
+ return $this;
161
+ }
162
+
163
+
164
+ /**
165
+ * Add search query filter
166
+ *
167
+ * @param Mage_CatalogSearch_Model_Query $query
168
+ *
169
+ * @return Mage_CatalogSearch_Model_Resource_Search_Collection
170
+ */
171
+ public function addSearchFilter($query)
172
+ {
173
+ return $this;
174
+ }
175
+
176
+
177
+ /**
178
+ * Set Order field
179
+ *
180
+ * @param string $attribute
181
+ * @param string $dir
182
+ *
183
+ * @return FACTFinder_Campaigns_Model_Resource_Pushedproducts_Collection
184
+ */
185
+ public function setOrder($attribute, $dir = 'desc')
186
+ {
187
+ return $this;
188
+ }
189
+
190
+
191
+ }
app/code/community/FACTFinder/Campaigns/etc/config.xml ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Campaigns
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Campaigns
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <config>
15
+ <modules>
16
+ <FACTFinder_Campaigns>
17
+ <version>4.0.1</version>
18
+ </FACTFinder_Campaigns>
19
+ </modules>
20
+ <global>
21
+ <models>
22
+ <factfinder_campaigns>
23
+ <class>FACTFinder_Campaigns_Model</class>
24
+ <resourceModel>factfinder_campaigns_resource</resourceModel>
25
+ </factfinder_campaigns>
26
+ <factfinder_campaigns_resource>
27
+ <class>FACTFinder_Campaigns_Model_Resource</class>
28
+ </factfinder_campaigns_resource>
29
+ </models>
30
+ <blocks>
31
+ <factfinder_campaigns>
32
+ <class>FACTFinder_Campaigns_Block</class>
33
+ </factfinder_campaigns>
34
+ </blocks>
35
+ <helpers>
36
+ <factfinder_campaigns>
37
+ <class>FACTFinder_Campaigns_Helper</class>
38
+ </factfinder_campaigns>
39
+ </helpers>
40
+ </global>
41
+ <frontend>
42
+ <events>
43
+ <controller_action_layout_generate_blocks_after>
44
+ <observers>
45
+ <factfinder_handle_campaigns_redirect>
46
+ <class>factfinder_campaigns/observer</class>
47
+ <method>handleCampaignsRedirect</method>
48
+ </factfinder_handle_campaigns_redirect>
49
+ </observers>
50
+ </controller_action_layout_generate_blocks_after>
51
+ </events>
52
+ <layout>
53
+ <updates>
54
+ <factfinder_campaigns>
55
+ <file>factfinder/campaigns.xml</file>
56
+ </factfinder_campaigns>
57
+ </updates>
58
+ </layout>
59
+ </frontend>
60
+ <default>
61
+ <factfinder>
62
+ <config>
63
+ <campaigns_identifier>sku</campaigns_identifier>
64
+ <enable_campaigns_on_prod_page>0</enable_campaigns_on_prod_page>
65
+ </config>
66
+ </factfinder>
67
+ </default>
68
+ </config>
app/code/community/FACTFinder/Campaigns/etc/system.xml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Campaigns
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Campaigns
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <config>
15
+ <sections>
16
+ <factfinder>
17
+ <groups>
18
+ <config>
19
+ <fields>
20
+ <campaigns_identifier translate="label">
21
+ <label>Campaigns Product Identifier</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>factfinder/system_config_source_identifier</source_model>
24
+ <sort_order>11</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </campaigns_identifier>
29
+ <enable_campaigns_on_prod_page>
30
+ <label>Enable campaigns on product page</label>
31
+ <frontend_type>select</frontend_type>
32
+ <source_model>adminhtml/system_config_source_yesno</source_model>
33
+ <sort_order>12</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>1</show_in_website>
36
+ <show_in_store>1</show_in_store>
37
+ </enable_campaigns_on_prod_page>
38
+ </fields>
39
+ </config>
40
+ </groups>
41
+ </factfinder>
42
+ </sections>
43
+ </config>
app/code/community/FACTFinder/Core/Block/Adminhtml/Exportlink.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Adminhtml export links renderer
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Block_Adminhtml_Exportlink extends Mage_Adminhtml_Block_System_Config_Form_Field
25
+ {
26
+
27
+
28
+ /**
29
+ * Get rendered link element html
30
+ *
31
+ * @param \Varien_Data_Form_Element_Abstract $element
32
+ *
33
+ * @return string
34
+ *
35
+ * @throws \Exception
36
+ * @throws \Mage_Core_Exception
37
+ */
38
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
39
+ {
40
+ $this->setElement($element);
41
+
42
+ $storeId = $this->getRequest()->getParam('store');
43
+ $websiteId = $this->getRequest()->getParam('website');
44
+
45
+ // define which store should be used
46
+ if ($websiteId && !$storeId) {
47
+ $store = Mage::app()->getWebsite($websiteId)->getDefaultStore();
48
+ } elseif (!$websiteId) {
49
+ $store = Mage::app()->getDefaultStoreView();
50
+ } else {
51
+ $store = Mage::app()->getStore($storeId);
52
+ }
53
+
54
+ $password = $store->getConfig('factfinder/search/auth_password');
55
+ $key = md5($password);
56
+
57
+ $urlParams = array(
58
+ 'key' => $key,
59
+ 'store' => $store->getId()
60
+ );
61
+
62
+ // Realtime export link
63
+ $html = $this->_createLink(
64
+ $store,
65
+ 'factfinder/export/export',
66
+ 'Trigger Realtime Export',
67
+ $urlParams
68
+ );
69
+
70
+ // Link to schedule cron export
71
+ if (Mage::getStoreConfig('factfinder/cron/enabled')) {
72
+ $html .= $this->_createLink(
73
+ $store,
74
+ 'factfinder/export/scheduleExport',
75
+ 'Schedule Cron Export (in 1 minute)',
76
+ $urlParams
77
+ );
78
+ }
79
+
80
+ // Download link for latest pre-generated product export
81
+ $fileName = 'store_' . $store->getId() . '_product.csv';
82
+ $filePath = Mage::getBaseDir('var') . DS . 'factfinder' . DS;
83
+
84
+ if (file_exists($filePath . $fileName)) {
85
+ $html .= $this->_createLink(
86
+ $store,
87
+ 'factfinder/export/download',
88
+ 'Download Last Pre-Generated Export',
89
+ $urlParams
90
+ );
91
+
92
+ // Link for FF Backend
93
+ $html .= $this->_createLink(
94
+ $store,
95
+ 'factfinder/export/get',
96
+ 'Export Link for FACT-Finder Wizard',
97
+ $urlParams
98
+ );
99
+ }
100
+
101
+ return $html;
102
+ }
103
+
104
+
105
+ /**
106
+ * Create html for a hyperlink
107
+ *
108
+ * @param Mage_Core_Model_Store $store
109
+ * @param string $route
110
+ * @param string $text
111
+ * @param array $params
112
+ *
113
+ * @return string
114
+ */
115
+ protected function _createLink(Mage_Core_Model_Store $store, $route, $text, $params)
116
+ {
117
+ $text = Mage::helper('factfinder')->__($text);
118
+
119
+ $url = Mage::app()->getStore($store)->getBaseUrl() . $route . '?';
120
+
121
+ foreach ($params as $key => $value) {
122
+ $url .= $key . '=' . $value . '&';
123
+ }
124
+
125
+ $href = rtrim($url, '&');
126
+
127
+ return "<a href=\"{$href}\" target=\"_blank\">{$text}</a><br />";
128
+ }
129
+
130
+
131
+ }
app/code/community/FACTFinder/Core/Block/Adminhtml/Form/Field/Attribute.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Core_Block_Adminhtml_Form_Field_Attribute
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Block_Adminhtml_Form_Field_Attribute extends Mage_Core_Block_Html_Select
25
+ {
26
+
27
+ /**
28
+ * Attributes cache
29
+ *
30
+ * @var array
31
+ */
32
+ protected $_attributes = array();
33
+
34
+
35
+ /**
36
+ * Retrieve attributes array
37
+ *
38
+ * @return array|string
39
+ */
40
+ protected function _getAttributes()
41
+ {
42
+ if (empty($this->_attributes)) {
43
+ $collection = Mage::getModel('eav/entity_attribute')->getCollection();
44
+ $collection->setEntityTypeFilter(Mage::getSingleton('eav/config')->getEntityType('catalog_product'));
45
+ foreach ($collection as $item) {
46
+ $code = $item->getAttributeCode();
47
+ /** @var $item Mage_Core_Model_Store */
48
+ $this->_attributes[$code] = $item->getFrontendLabel().' ('.$code.')';
49
+ }
50
+ }
51
+
52
+ return $this->_attributes;
53
+ }
54
+
55
+
56
+ /**
57
+ * Set name of the html input
58
+ *
59
+ * @param string $value
60
+ *
61
+ * @return mixed
62
+ */
63
+ public function setInputName($value)
64
+ {
65
+ return $this->setName($value);
66
+ }
67
+
68
+
69
+ /**
70
+ * Render block HTML
71
+ *
72
+ * @return string
73
+ */
74
+ public function _toHtml()
75
+ {
76
+ if (!$this->getOptions()) {
77
+ foreach ($this->_getAttributes() as $id => $label) {
78
+ $htmlLabel = htmlspecialchars($label, ENT_QUOTES);
79
+ $this->addOption($id, $htmlLabel);
80
+ }
81
+ }
82
+
83
+ return parent::_toHtml();
84
+ }
85
+
86
+
87
+ }
app/code/community/FACTFinder/Core/Block/Adminhtml/Form/Field/Attributes.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Adminhtml system comfiguration attributes renderer
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Block_Adminhtml_Form_Field_Attributes
25
+ extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
26
+ {
27
+
28
+ /**
29
+ * @var FACTFinder_Core_Block_Adminhtml_Form_Field_Attribute
30
+ */
31
+ protected $_attributeRenderer;
32
+
33
+
34
+ /**
35
+ * Retrieve group column renderer
36
+ *
37
+ * @return FACTFinder_Core_Block_Adminhtml_Form_Field_Attribute
38
+ */
39
+ protected function _getAttributeRenderer()
40
+ {
41
+ if (!$this->_attributeRenderer) {
42
+ $this->_attributeRenderer = $this->getLayout()->createBlock(
43
+ 'factfinder/adminhtml_form_field_attribute', '',
44
+ array('is_render_to_js_template' => true)
45
+ );
46
+ $this->_attributeRenderer->setClass('attribute_select');
47
+ $this->_attributeRenderer->setExtraParams('style="width:200px"');
48
+ }
49
+
50
+ return $this->_attributeRenderer;
51
+ }
52
+
53
+
54
+ /**
55
+ * Prepare to render
56
+ *
57
+ * @return void
58
+ */
59
+ protected function _prepareToRender()
60
+ {
61
+ $this->addColumn('attribute', array(
62
+ 'label' => Mage::helper('factfinder')->__('Attribute'),
63
+ 'renderer' => $this->_getAttributeRenderer(),
64
+ ));
65
+
66
+ $this->_addAfter = false;
67
+ $this->_addButtonLabel = Mage::helper('factfinder')->__('Add Attribute');
68
+ }
69
+
70
+
71
+ /**
72
+ * Prepare existing row data object
73
+ *
74
+ * @param Varien_Object $row
75
+ *
76
+ * @return void
77
+ */
78
+ protected function _prepareArrayRow(Varien_Object $row)
79
+ {
80
+ $row->setData(
81
+ 'option_extra_attr_' . $this->_getAttributeRenderer()->calcOptionHash($row->getData('attribute')),
82
+ 'selected="selected"'
83
+ );
84
+ }
85
+
86
+
87
+ }
88
+
app/code/community/FACTFinder/Core/Block/Catalog/Product/List/Toolbar.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Replaces default toolbar
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Block_Catalog_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar
25
+ {
26
+
27
+ /**
28
+ * @var bool
29
+ */
30
+ protected $_useFF = true;
31
+
32
+ /**
33
+ * @var FACTFinder_Core_Model_Handler_Search
34
+ */
35
+ protected $_handler;
36
+
37
+ /**
38
+ * @var array
39
+ */
40
+ protected $_sortings = array();
41
+
42
+
43
+ /**
44
+ * Constructor
45
+ *
46
+ * @return void
47
+ */
48
+ protected function _construct()
49
+ {
50
+ if ($this->_useFF && Mage::helper('factfinder')->isEnabled()) {
51
+ $this->_handler = Mage::getSingleton('factfinder/handler_search');
52
+ }
53
+
54
+ parent::_construct();
55
+ }
56
+
57
+
58
+ /**
59
+ * Get page url
60
+ *
61
+ * @param array $params
62
+ *
63
+ * @return string
64
+ */
65
+ public function getPagerUrl($params=array())
66
+ {
67
+ $sortingId = $this->_getSortingId($params);
68
+
69
+ if ($sortingId && $this->_handler) {
70
+ $sortings = $this->_handler->getSorting();
71
+
72
+ // relevance default and has no directions
73
+ if ($sortingId == $this->_orderField) {
74
+ $sorting = $sortings[0];
75
+ $this->_sortings[$sortingId] = $sorting->getUrl();
76
+ } elseif (!isset($this->_sortings[$sortingId])) {
77
+ /** @var \FACTFinder\Data\Item $sorting */
78
+ foreach ($sortings as $sorting) {
79
+ $url = $sorting->getUrl();
80
+ if (strpos($url, $sortingId) !== false) {
81
+ $this->_sortings[$sortingId] = $sorting->getUrl();
82
+ break;
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ if (isset($this->_sortings[$sortingId])) {
89
+ return $this->_sortings[$sortingId];
90
+ } else {
91
+ return parent::getPagerUrl($params);
92
+ }
93
+ }
94
+
95
+
96
+ /**
97
+ * @param int $limit
98
+ *
99
+ * @return string
100
+ */
101
+ public function getLimitUrl($limit)
102
+ {
103
+ $params = array(
104
+ $this->getLimitVarName() => $limit,
105
+ );
106
+
107
+ $query = http_build_query($params);
108
+
109
+ $url = trim(Mage::getBaseUrl('web'), '/');
110
+
111
+ // using super global because magento doesn't return real uri
112
+ // but its target like catalog/category/view
113
+ $currentRequest = explode('?', $this->removeBasePathByBaseUrl($_SERVER['REQUEST_URI'], $url));
114
+
115
+ if (count($currentRequest) > 1) {
116
+ $params = array_pop($currentRequest);
117
+ $params = $this->_removeParam($params, 'limit');
118
+ $params = $this->_removeParam($params, 'p');
119
+
120
+ $currentRequest = array_pop($currentRequest);
121
+
122
+ return $url . $currentRequest . '?' . $params . '&' . $query;
123
+ } else {
124
+ return parent::getPagerUrl($params);
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Uses a given base URL to remove subfolders from the current request path in case Magento is hosted in a
130
+ * subdirectory.
131
+ *
132
+ * @param string $fullPath The full request path.
133
+ * @param string $baseUrl The base URL of the Magento installation.
134
+ * @return string
135
+ */
136
+ private function removeBasePathByBaseUrl($fullPath, $baseUrl){
137
+ $basePath = parse_url($baseUrl, PHP_URL_PATH);
138
+ $pos = strpos($fullPath, $basePath);
139
+ if ($pos !== false) {
140
+ return substr_replace($fullPath, '', $pos, strlen($basePath));
141
+ }
142
+ return $fullPath;
143
+ }
144
+
145
+ /**
146
+ * Get sorting id
147
+ *
148
+ * @param array $params
149
+ *
150
+ * @return bool|string
151
+ */
152
+ protected function _getSortingId($params)
153
+ {
154
+ if (isset($params[$this->getOrderVarName()]) && isset($params[$this->getDirectionVarName()])) {
155
+ if ($params[$this->getOrderVarName()] == $this->_orderField) {
156
+ return $this->_orderField;
157
+ }
158
+
159
+ return 'sort' . $params[$this->getOrderVarName()] . '=' . $params[$this->getDirectionVarName()];
160
+ }
161
+
162
+ return false;
163
+ }
164
+
165
+
166
+ /**
167
+ * Get grit products sort order field
168
+ *
169
+ * @return string
170
+ */
171
+ public function getCurrentOrder()
172
+ {
173
+ if (!$this->_handler) {
174
+ return parent::getCurrentOrder();
175
+ }
176
+
177
+ $order = $this->_getData('_current_grid_order');
178
+ if ($order) {
179
+ return $order;
180
+ }
181
+
182
+ $orders = $this->getAvailableOrders();
183
+ $defaultOrder = $this->_orderField;
184
+
185
+ if (!isset($orders[$defaultOrder])) {
186
+ $keys = array_keys($orders);
187
+ $defaultOrder = $keys[0];
188
+ }
189
+
190
+ // the only change of this method is here
191
+ $order = $this->_getSelectedOrder();
192
+
193
+ if ($order && isset($orders[$order])) {
194
+ if ($order == $defaultOrder) {
195
+ Mage::getSingleton('catalog/session')->unsSortOrder();
196
+ } else {
197
+ $this->_memorizeParam('sort_order', $order);
198
+ }
199
+ } else {
200
+ $order = Mage::getSingleton('catalog/session')->getSortOrder();
201
+ }
202
+
203
+ // validate session value
204
+ if (!$order || !isset($orders[$order])) {
205
+ $order = $defaultOrder;
206
+ }
207
+
208
+ $this->setData('_current_grid_order', $order);
209
+
210
+ return $order;
211
+ }
212
+
213
+
214
+ /**
215
+ * Get current order
216
+ *
217
+ * @return string
218
+ *
219
+ * @throws \Exception
220
+ */
221
+ protected function _getSelectedOrder()
222
+ {
223
+ if ($this->_handler && $this->_handler->getSorting()) {
224
+ $sortings = $this->_handler->getSorting();
225
+
226
+ $this->getRequest()->getQuery();
227
+ /** @var \FACTFinder\Data\Item $sorting */
228
+ foreach ($sortings as $sorting) {
229
+ if ($sorting->isSelected()) {
230
+ $url = $sorting->getUrl();
231
+ preg_match('/[\?|\&]{1}sort([a-z0-9\_]*?)=/', $url, $matches);
232
+ if (isset($matches[1])) {
233
+ return $matches[1];
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ return $this->_orderField;
240
+ }
241
+
242
+
243
+ /**
244
+ * Get var name for sorting direction
245
+ *
246
+ * @return string
247
+ */
248
+ public function getDirectionVarName()
249
+ {
250
+ if ($this->_handler) {
251
+ return 'sort' . $this->getCurrentOrder();
252
+ }
253
+
254
+ return parent::getDirectionVarName();
255
+ }
256
+
257
+
258
+ /**
259
+ * Remove specific parameter from url parameters string
260
+ *
261
+ * @param string $paramString
262
+ * @param string $paramName
263
+ *
264
+ * @return string
265
+ */
266
+ protected function _removeParam($paramString, $paramName)
267
+ {
268
+
269
+ $params = explode('&', $paramString);
270
+ foreach ($params as $key => $part) {
271
+ if (strpos($part, $paramName . '=') === 0) {
272
+ unset($params[$key]);
273
+ }
274
+ }
275
+
276
+ return implode('&', $params);
277
+ }
278
+
279
+
280
+ }
app/code/community/FACTFinder/Core/Block/Catalog/Product/Pager.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Replaces default pager
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Block_Catalog_Product_Pager extends Mage_Page_Block_Html_Pager
25
+ {
26
+
27
+ /**
28
+ * Whether FF should be used to get paging urls
29
+ *
30
+ * @var bool
31
+ */
32
+ protected $_useFF = true;
33
+
34
+ /**
35
+ * @var FACTFinder_Core_Model_Handler_Search
36
+ */
37
+ protected $_handler;
38
+
39
+ /**
40
+ * @var array
41
+ */
42
+ protected $_pagingUrls = array();
43
+
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @return void
49
+ */
50
+ protected function _construct()
51
+ {
52
+ if ($this->_useFF) {
53
+ $this->_handler = Mage::getSingleton('factfinder/handler_search');
54
+ }
55
+
56
+ parent::_construct();
57
+ }
58
+
59
+
60
+ /**
61
+ * Get pager url with specific params
62
+ *
63
+ * @param array $params
64
+ *
65
+ * @return string
66
+ */
67
+ public function getPagerUrl($params = array())
68
+ {
69
+ if (!$this->_handler || !$this->_handler->getPaging()) {
70
+ return parent::getPagerUrl($params);
71
+ }
72
+
73
+ $pageNum = $params['p'];
74
+
75
+ if (!isset($this->_pagingUrls[$pageNum])) {
76
+ $this->_pagingUrls[$pageNum] = '';
77
+ /** @var \FACTFinder\Data\Page $pageItem */
78
+ foreach ($this->_handler->getPaging() as $pageItem) {
79
+ if ($pageItem->getPageNumber() == $pageNum) {
80
+ $this->_pagingUrls[$pageNum] = $pageItem->getUrl();
81
+ break;
82
+ }
83
+ }
84
+ }
85
+
86
+ return $this->_pagingUrls[$pageNum];
87
+ }
88
+
89
+
90
+ }
app/code/community/{Flagbit/FactFinder → FACTFinder/Core}/Helper/Backend.php RENAMED
@@ -1,228 +1,248 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Helper class
12
- *
13
- * Helper for backend configurations.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2011 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Enabled.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Helper_Backend extends Mage_Core_Helper_Abstract
22
- {
23
-
24
- /**
25
- * Check configuration data by contacting FACT-Finder servers.
26
- *
27
- * @param unknown_type $configData
28
- */
29
- public function checkConfigData($configData) {
30
- $dataArray = $this->_getCompleteFieldsetData($configData);
31
- $data = new Varien_Object($dataArray);
32
- $errors = array();
33
-
34
- if (stripos($data->getAddress(), 'http://') === 0 || strpos($data->getAddress(), '/') !== false) {
35
- $errors[] = Mage::helper('factfinder')->__('The server name should contain only the IP address or the domain - no "http://" or any slashes!');
36
- }
37
-
38
- if ($data->getPort() == '') {
39
- $port = 80;
40
- }
41
- elseif (!is_numeric($data->getPort())) {
42
- $errors[] = Mage::helper('factfinder')->__('The value for "port" must be an integer!');
43
- }
44
- elseif(intval($data->getPort()) < 80) { //is there any http port lower 80?
45
- $errors[] = Mage::helper('factfinder')->__('The value for "port" must be an integer greater or equals 80!');
46
- }
47
-
48
- if ($data->getAuthPassword() != '' && $data->getAuthUser() == '') {
49
- $errors[] = Mage::helper('factfinder')->__('A user name must be provided if a password is to be used.');
50
- }
51
-
52
- $conflicts = Mage::helper('factfinder/debug')->getRewriteConflicts();
53
- if(count($conflicts)){
54
- foreach($conflicts as $moduleClass => $externalClass){
55
- $errors[] = Mage::helper('factfinder')->__('There is a Class Rewrite Conflict: "%s" already overwritten by "%s"', $moduleClass, $externalClass);
56
- }
57
- }
58
-
59
- if (count($errors) == 0) {
60
- $checkStatusHandler = Mage::getSingleton('factfinder/handler_checkStatus', $dataArray);
61
- if(!$checkStatusHandler->checkStatus($data->getFfversion())){
62
- $errors = $checkStatusHandler->getErrorMessages();
63
- }
64
- }
65
-
66
- return $errors;
67
- }
68
-
69
-
70
-
71
- /**
72
- * Read data from array given, or if no value given, try to read data from website or global configuration
73
- *
74
- * @param array $configData
75
- */
76
- protected function _getCompleteFieldsetData($configData)
77
- {
78
- $data = array();
79
- $websiteCode = Mage::app()->getRequest()->getParam('website');
80
- $storeCode = Mage::app()->getRequest()->getParam('store');
81
-
82
- foreach ($configData as $key => $keyData) {
83
- if (!isset($keyData['value'])) {
84
-
85
- $path = 'factfinder/search/' . $key;
86
-
87
- if ($storeCode) {
88
- $value = Mage::app()->getWebsite($websiteCode)->getConfig($path);
89
- }
90
- else {
91
- $value = (string) Mage::getConfig()->getNode('default/' . $path);
92
- }
93
- }
94
- else {
95
- $value = $keyData['value'];
96
- }
97
-
98
- $data[$key] = $value;
99
- }
100
-
101
- return $data;
102
- }
103
-
104
- /**
105
- * Generate a storable representation of a value
106
- *
107
- * @param mixed $value
108
- * @return string
109
- */
110
- protected function _serializeValue($value)
111
- {
112
- if (is_array($value)) {
113
- $data = array();
114
- foreach ($value as $rule => $setup) {
115
- if($rule == '__empty') {
116
- continue;
117
- }
118
- if (!array_key_exists($rule, $data)) {
119
- $data[$rule] = $setup;
120
- }
121
- }
122
- return serialize($data);
123
- } else {
124
- return '';
125
- }
126
- }
127
-
128
- /**
129
- * Create a value from a storable representation
130
- *
131
- * @param mixed $value
132
- * @return array
133
- */
134
- protected function _unserializeValue($value)
135
- {
136
- if (is_string($value) && !empty($value)) {
137
- return unserialize($value);
138
- } else {
139
- return array();
140
- }
141
- }
142
-
143
- /**
144
- * Check whether value is in form retrieved by _encodeArrayFieldValue()
145
- *
146
- * @param mixed
147
- * @return bool
148
- */
149
- protected function _isEncodedArrayFieldValue($value)
150
- {
151
- if (!is_array($value)) {
152
- return false;
153
- }
154
- unset($value['__empty']);
155
- foreach ($value as $_id => $row) {
156
- if (!is_array($row) || !array_key_exists('attribute', $row)) {
157
- return false;
158
- }
159
- }
160
- return true;
161
- }
162
-
163
- /**
164
- * Encode value to be used in Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
165
- *
166
- * @param array
167
- * @return array
168
- */
169
- protected function _encodeArrayFieldValue(array $value)
170
- {
171
- $result = array();
172
- foreach ($value as $set => $value) {
173
- $_id = Mage::helper('core')->uniqHash('_');
174
- $result[$_id] = $value;
175
- }
176
- return $result;
177
- }
178
-
179
- /**
180
- * Decode value from used in Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
181
- *
182
- * @param array
183
- * @return array
184
- */
185
- protected function _decodeArrayFieldValue(array $value)
186
- {
187
- $result = array();
188
- unset($value['__empty']);
189
- foreach ($value as $_id => $row) {
190
- if (!is_array($row) || !array_key_exists('attribute', $row)) {
191
- continue;
192
- }
193
- $result[trim($row['attribute'])] = $row;
194
- }
195
- return $result;
196
- }
197
-
198
- /**
199
- * Make value readable by Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
200
- *
201
- * @param mixed $value
202
- * @return array
203
- */
204
- public function makeArrayFieldValue($value)
205
- {
206
- $value = $this->_unserializeValue($value);
207
- if (!$this->_isEncodedArrayFieldValue($value)) {
208
- $value = $this->_encodeArrayFieldValue($value);
209
- }
210
- return $value;
211
- }
212
-
213
- /**
214
- * Make value ready for store
215
- *
216
- * @param mixed $value
217
- * @return string
218
- */
219
- public function makeStorableArrayFieldValue($value)
220
- {
221
- if ($this->_isEncodedArrayFieldValue($value)) {
222
- $value = $this->_decodeArrayFieldValue($value);
223
- }
224
- $value = $this->_serializeValue($value);
225
- return $value;
226
- }
227
-
228
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * Helper for backend configurations.
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Helper_Backend extends Mage_Core_Helper_Abstract
27
+ {
28
+
29
+
30
+ /**
31
+ * Generate a storable representation of a value
32
+ *
33
+ * @param mixed $value
34
+ *
35
+ * @return string
36
+ */
37
+ protected function _serializeValue($value)
38
+ {
39
+ if (!is_array($value)) {
40
+ return '';
41
+ }
42
+
43
+ $data = array();
44
+ foreach ($value as $rule => $setup) {
45
+ if ($rule == '__empty') {
46
+ continue;
47
+ }
48
+
49
+ if (!array_key_exists($rule, $data)) {
50
+ $data[$rule] = $setup;
51
+ }
52
+ }
53
+
54
+ return serialize($data);
55
+ }
56
+
57
+
58
+ /**
59
+ * Create a value from a storable representation
60
+ *
61
+ * @param mixed $value
62
+ *
63
+ * @return array
64
+ */
65
+ protected function _unserializeValue($value)
66
+ {
67
+ if (is_string($value) && !empty($value)) {
68
+ return unserialize($value);
69
+ } else {
70
+ return array();
71
+ }
72
+ }
73
+
74
+
75
+ /**
76
+ * Check whether value is in form retrieved by _encodeArrayFieldValue()
77
+ *
78
+ * @param mixed $value
79
+ *
80
+ * @return bool
81
+ */
82
+ protected function _isEncodedArrayFieldValue($value)
83
+ {
84
+ if (!is_array($value)) {
85
+ return false;
86
+ }
87
+
88
+ unset($value['__empty']);
89
+ foreach ($value as $_id => $row) {
90
+ if (!is_array($row) || !array_key_exists('attribute', $row)) {
91
+ return false;
92
+ }
93
+ }
94
+
95
+ return true;
96
+ }
97
+
98
+
99
+ /**
100
+ * Encode value to be used in Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
101
+ *
102
+ * @param array $data
103
+ *
104
+ * @return array
105
+ */
106
+ protected function _encodeArrayFieldValue(array $data)
107
+ {
108
+ $result = array();
109
+ foreach ($data as $set => $value) {
110
+ $_id = Mage::helper('core')->uniqHash('_');
111
+ $result[$_id] = $value;
112
+ }
113
+
114
+ return $result;
115
+ }
116
+
117
+
118
+ /**
119
+ * Decode value from used in Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
120
+ *
121
+ * @param array $data
122
+ *
123
+ * @return array
124
+ */
125
+ protected function _decodeArrayFieldValue(array $data)
126
+ {
127
+ $result = array();
128
+ unset($data['__empty']);
129
+ foreach ($data as $_id => $row) {
130
+ if (!is_array($row) || !array_key_exists('attribute', $row)) {
131
+ continue;
132
+ }
133
+
134
+ $result[trim($row['attribute'])] = $row;
135
+ }
136
+
137
+ return $result;
138
+ }
139
+
140
+
141
+ /**
142
+ * Make value readable by Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
143
+ *
144
+ * @param mixed $value
145
+ *
146
+ * @return array
147
+ */
148
+ public function unserializeFieldValue($value)
149
+ {
150
+ $value = $this->_unserializeValue($value);
151
+ if (!$this->_isEncodedArrayFieldValue($value)) {
152
+ $value = $this->_encodeArrayFieldValue($value);
153
+ }
154
+
155
+ return $value;
156
+ }
157
+
158
+
159
+ /**
160
+ * Make value ready for store
161
+ *
162
+ * @param mixed $value
163
+ *
164
+ * @return string
165
+ */
166
+ public function serializeFieldValue($value)
167
+ {
168
+ if ($this->_isEncodedArrayFieldValue($value)) {
169
+ $value = $this->_decodeArrayFieldValue($value);
170
+ }
171
+
172
+ $value = $this->_serializeValue($value);
173
+
174
+ return $value;
175
+ }
176
+
177
+
178
+ /**
179
+ * Check configuration data by contacting FACT-Finder servers.
180
+ *
181
+ * @param array $configData
182
+ *
183
+ * @return array
184
+ */
185
+ public function checkConfigData($configData)
186
+ {
187
+ $dataArray = $this->_getCompleteFieldsetData($configData);
188
+ $data = new Varien_Object($dataArray);
189
+ $errors = array();
190
+
191
+ if (stripos($data->getAddress(), 'http://') === 0 || strpos($data->getAddress(), '/') !== false) {
192
+ $errors[] = Mage::helper('factfinder')
193
+ ->__('The server name should contain only the IP address or the domain - no "http://" or any slashes!');
194
+ } elseif (!is_numeric($data->getPort())) {
195
+ $errors[] = Mage::helper('factfinder')->__('The value for "port" must be an integer!');
196
+ } elseif (intval($data->getPort()) < 80) { //is there any http port lower 80?
197
+ $errors[] = Mage::helper('factfinder')->__('The value for "port" must be an integer greater or equals 80!');
198
+ }
199
+
200
+ if ($data->getAuthPassword() != '' && $data->getAuthUser() == '') {
201
+ $errors[] = Mage::helper('factfinder')->__('A user name must be provided if a password is to be used.');
202
+ }
203
+
204
+ if (count($errors) == 0) {
205
+ $checkStatusHandler = Mage::getSingleton('factfinder/handler_status', $dataArray);
206
+ if (!$checkStatusHandler->checkStatus()) {
207
+ $errors = $checkStatusHandler->getErrorMessages();
208
+ }
209
+ }
210
+
211
+ return $errors;
212
+ }
213
+
214
+
215
+ /**
216
+ * Read data from array given, or if no value given, try to read data from website or global configuration
217
+ *
218
+ * @param array $configData
219
+ *
220
+ * @return array
221
+ */
222
+ protected function _getCompleteFieldsetData($configData)
223
+ {
224
+ $data = array();
225
+ $websiteCode = Mage::app()->getRequest()->getParam('website');
226
+ $storeCode = Mage::app()->getRequest()->getParam('store');
227
+
228
+ foreach ($configData as $key => $keyData) {
229
+ if (!isset($keyData['value'])) {
230
+ $path = 'factfinder/search/' . $key;
231
+
232
+ if ($storeCode) {
233
+ $value = Mage::app()->getWebsite($websiteCode)->getConfig($path);
234
+ } else {
235
+ $value = (string) Mage::getConfig()->getNode('default/' . $path);
236
+ }
237
+ } else {
238
+ $value = $keyData['value'];
239
+ }
240
+
241
+ $data[$key] = $value;
242
+ }
243
+
244
+ return $data;
245
+ }
246
+
247
+
248
+ }
app/code/community/FACTFinder/Core/Helper/Data.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Helper_Data extends Mage_Core_Helper_Abstract
25
+ {
26
+
27
+ const SKIP_FF_PARAM_NAME = 'skip_ff';
28
+
29
+
30
+ /**
31
+ * Check if the module is enabled
32
+ *
33
+ * @param string|null $feature
34
+ *
35
+ * @return bool
36
+ */
37
+ public function isEnabled($feature = null)
38
+ {
39
+ if ($this->_getRequest()->getParam('skip_ff')) {
40
+ return false;
41
+ }
42
+
43
+ $result = (bool) Mage::app()->getStore()->getConfig('factfinder/search/enabled');
44
+ if ($feature !== null) {
45
+ $result &= (bool) Mage::app()->getStore()->getConfig('factfinder/modules/' . $feature);
46
+ }
47
+
48
+ return $result;
49
+ }
50
+
51
+
52
+ /**
53
+ * Check if the sub-module was activated in config
54
+ *
55
+ * @param string $module
56
+ *
57
+ * @return bool
58
+ */
59
+ public function isModuleActivated($module)
60
+ {
61
+ return (bool) Mage::app()->getStore()->getConfig('advanced/ff_modules/' . $module);
62
+ }
63
+
64
+
65
+ /**
66
+ * Check if the request is from internal IP address
67
+ *
68
+ * @return bool
69
+ */
70
+ public function isInternal()
71
+ {
72
+ $internalIp = Mage::getStoreConfig('factfinder/config/internal_ip');
73
+ $currentIp = Mage::helper('core/http')->getRemoteAddr();
74
+
75
+ return strpos($internalIp, $currentIp) !== false;
76
+ }
77
+
78
+
79
+ /**
80
+ * Update xml file in etc/modules according to backend config
81
+ * Return true, if the file was written and false if an error occurred
82
+ *
83
+ * @param string $module
84
+ * @param bool $isActive
85
+ *
86
+ * @return bool
87
+ */
88
+ public function updateModuleState($module, $isActive = true)
89
+ {
90
+ $dir = Mage::getBaseDir('etc') . DS . 'modules' . DS;
91
+ $file = $dir . $module . '.xml';
92
+
93
+ if (!file_exists($file)) {
94
+ return;
95
+ }
96
+
97
+ $xml = new DOMDocument();
98
+ $xml->load($file);
99
+ foreach ($xml->getElementsByTagName('active') as $item) {
100
+ $item->nodeValue = $isActive ? 'true' : 'false';
101
+ }
102
+
103
+ // silencing is not good, but we only need the result of the operation
104
+ return (bool) @$xml->save($file);
105
+ }
106
+
107
+
108
+ /**
109
+ * Redirect to the same url but with the skip parameter
110
+ *
111
+ * @return void
112
+ */
113
+ public function performFallbackRedirect()
114
+ {
115
+ if (!$this->_getRequest()->getParam(self::SKIP_FF_PARAM_NAME)
116
+ && Mage::getStoreConfig('factfinder/fallback/use_fallback')
117
+ ) {
118
+ $url = Mage::helper('core/url')->getCurrentUrl();
119
+ $url .= strpos($url, '?') ? '&' : '?';
120
+ $url .= self::SKIP_FF_PARAM_NAME . '=1';
121
+ Mage::app()->getResponse()->setRedirect($url)
122
+ ->sendResponse();
123
+ exit(0);
124
+ }
125
+ }
126
+
127
+
128
+ /**
129
+ * Check whether import must be triggered
130
+ *
131
+ * @param null|int $storeId
132
+ *
133
+ * @return bool
134
+ */
135
+ public function isImportTriggerEnabled($storeId = null)
136
+ {
137
+ return Mage::getStoreConfigFlag('factfinder/export/trigger_data_import', $storeId);
138
+ }
139
+
140
+
141
+ /**
142
+ * Get list of channels for store
143
+ *
144
+ * @param null|int $storeId
145
+ *
146
+ * @return array
147
+ */
148
+ public function getStoreChannels($storeId = null)
149
+ {
150
+ $primary = Mage::getStoreConfig('factfinder/search/channel', $storeId);
151
+ $secondary = Mage::getStoreConfig('factfinder/search/secondary_channels', $storeId);
152
+ $secondary = explode(';', $secondary);
153
+
154
+ return array_merge(array($primary), $secondary);
155
+ }
156
+
157
+
158
+ }
app/code/community/FACTFinder/Core/Helper/Debug.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Helper_Debug extends Mage_Core_Helper_Abstract
25
+ implements FACTFinder\Util\LoggerInterface
26
+ {
27
+
28
+ /**
29
+ * Module Configuration File
30
+ *
31
+ * @var string
32
+ */
33
+ const MODULE_CONFIG_FILE = 'config.xml';
34
+
35
+ /**
36
+ * Module Log File
37
+ *
38
+ * @var string
39
+ */
40
+ const LOG_FILE_NAME = 'factfinder.log';
41
+
42
+ /**
43
+ * XML Config Path to Product Identifier Setting
44
+ *
45
+ * @var string
46
+ */
47
+ const XML_CONFIG_PATH_DEBUG_MODE = 'factfinder/config/debug';
48
+
49
+ /**
50
+ * @var Log4PhpLogger
51
+ */
52
+ protected static $_loggerInstance = null;
53
+
54
+
55
+ /**
56
+ * Returns a new logger with the given name.
57
+ *
58
+ * @param string $name Name of the logger. This should be the fully
59
+ * qualified name of the class using this instance,
60
+ * so that different sub-namespaces can be configured
61
+ * differently. Note that in the configuration file, the
62
+ * loggers need to be qualified with periods instead of
63
+ * backslashes.
64
+ *
65
+ * @return Log4PhpLogger
66
+ */
67
+ public static function getLogger($name)
68
+ {
69
+ if (self::$_loggerInstance === null) {
70
+ self::$_loggerInstance = new self;
71
+ }
72
+
73
+ return self::$_loggerInstance;
74
+ }
75
+
76
+
77
+ /**
78
+ * Check if the debug mode is enabled
79
+ *
80
+ * @return bool
81
+ */
82
+ public function isDebugMode()
83
+ {
84
+ return (bool) Mage::getStoreConfig(self::XML_CONFIG_PATH_DEBUG_MODE);
85
+ }
86
+
87
+
88
+ /**
89
+ * Debug Log to file var/log/factfinder.log
90
+ *
91
+ * @param mixed $message
92
+ *
93
+ * @return $this
94
+ */
95
+ public function log($message)
96
+ {
97
+ if (!Mage::getConfig()) {
98
+ return $this;
99
+ }
100
+
101
+ try {
102
+ if ($this->isDebugMode()) {
103
+ Mage::log($message, null, self::LOG_FILE_NAME, true);
104
+ }
105
+ } catch (Exception $e){
106
+ // actually do nothing
107
+ return $this;
108
+ }
109
+
110
+ return $this;
111
+ }
112
+
113
+
114
+ /**
115
+ * Log message with prefix TRACE
116
+ *
117
+ * @param mixed $message
118
+ *
119
+ * @return \FACTFinder_Core_Helper_Debug
120
+ */
121
+ public function trace($message)
122
+ {
123
+ return $this->log('TRACE: ' . $message);
124
+ }
125
+
126
+
127
+ /**
128
+ * Log message with prefix TRACE
129
+ *
130
+ * @param mixed $message
131
+ *
132
+ * @return \FACTFinder_Core_Helper_Debug
133
+ */
134
+ public function debug($message)
135
+ {
136
+ return $this->log('DEBUG: ' . $message);
137
+ }
138
+
139
+
140
+ /**
141
+ * Log message with prefix INFO
142
+ *
143
+ * @param mixed $message
144
+ *
145
+ * @return \FACTFinder_Core_Helper_Debug
146
+ */
147
+ public function info($message)
148
+ {
149
+ return $this->log('INFO: ' . $message);
150
+ }
151
+
152
+
153
+ /**
154
+ * Log message with prefix WARNING
155
+ *
156
+ * @param mixed $message
157
+ *
158
+ * @return \FACTFinder_Core_Helper_Debug
159
+ */
160
+ public function warn($message)
161
+ {
162
+ return $this->log('WARNING: ' . $message);
163
+ }
164
+
165
+
166
+ /**
167
+ * Log message with prefix ERROR
168
+ *
169
+ * @param mixed $message
170
+ *
171
+ * @return \FACTFinder_Core_Helper_Debug
172
+ */
173
+ public function error($message)
174
+ {
175
+ return $this->log('ERROR: ' . $message);
176
+ }
177
+
178
+
179
+ /**
180
+ * Log message with prefix FATAL ERROR
181
+ *
182
+ * @param mixed $message
183
+ *
184
+ * @return \FACTFinder_Core_Helper_Debug
185
+ */
186
+ public function fatal($message)
187
+ {
188
+ return $this->log('FATAL ERROR: ' . $message);
189
+ }
190
+
191
+
192
+ }
app/code/community/FACTFinder/Core/Helper/Search.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Helper_Search extends Mage_Core_Helper_Abstract
25
+ {
26
+ /**
27
+ * XML Config Path to Product Identifier Setting
28
+ *
29
+ * @var string
30
+ */
31
+ const XML_CONFIG_PATH_PRODUCT_IDENTIFIER = 'factfinder/config/identifier';
32
+
33
+ const REQUEST_ID_PREFIX = 'FACTFINDER_';
34
+
35
+ const DEFAULT_ENTITY_ID_FIELD_NAME = 'entity_id';
36
+
37
+
38
+ /**
39
+ * Retrieve query model object
40
+ *
41
+ * @return String
42
+ */
43
+ public function getQueryText()
44
+ {
45
+ return strip_tags(Mage::helper('catalogsearch')->getQueryText());
46
+ }
47
+
48
+
49
+ /**
50
+ * get Page Limit
51
+ *
52
+ * @return int
53
+ */
54
+ public function getPageLimit()
55
+ {
56
+ $limit = $this->_getToolbarBlock()->getLimit();
57
+ if ($limit == 'all') {
58
+ $limit = 720; // number of products to fit for each layout: 2 * 3 * 4 * 5 * 6 per row
59
+ }
60
+
61
+ return $limit;
62
+ }
63
+
64
+
65
+ /**
66
+ * get Toolbar Block
67
+ *
68
+ * @return Mage_Catalog_Block_Product_List_Toolbar
69
+ */
70
+ protected function _getToolbarBlock()
71
+ {
72
+ $mainBlock = Mage::app()->getLayout()->getBlock('search.result');
73
+ if ($mainBlock instanceof Mage_CatalogSearch_Block_Result) {
74
+ $toolbarBlock = $mainBlock->getListBlock()->getToolbarBlock();
75
+ } else {
76
+ $toolbarBlock = Mage::app()->getLayout()->createBlock('catalog/product_list_toolbar');
77
+ }
78
+
79
+ return $toolbarBlock;
80
+ }
81
+
82
+
83
+ /**
84
+ * get current Page Number
85
+ *
86
+ * @return int
87
+ */
88
+ public function getCurrentPage()
89
+ {
90
+ return $this->_getToolbarBlock()->getCurrentPage();
91
+ }
92
+
93
+
94
+ /**
95
+ * get Entity ID Field Name by Configuration or via Entity
96
+ *
97
+ * @return string
98
+ */
99
+ public function getIdFieldName()
100
+ {
101
+ $idFieldName = Mage::getStoreConfig(self::XML_CONFIG_PATH_PRODUCT_IDENTIFIER);
102
+ if (!$idFieldName) {
103
+ $idFieldName = self::DEFAULT_ENTITY_ID_FIELD_NAME;
104
+ }
105
+
106
+ return $idFieldName;
107
+ }
108
+
109
+
110
+ /**
111
+ * Retrieve default per page values
112
+ *
113
+ * @return string (comma separated)
114
+ */
115
+ public function getDefaultPerPageValue()
116
+ {
117
+ return $this->_getToolbarBlock()->getDefaultPerPageValue();
118
+ }
119
+
120
+
121
+ /**
122
+ * get current Order
123
+ *
124
+ * @return string
125
+ */
126
+ public function getCurrentOrder()
127
+ {
128
+ return $this->_getToolbarBlock()->getCurrentOrder();
129
+ }
130
+
131
+
132
+ /**
133
+ * get current Order Direction
134
+ *
135
+ * @return string
136
+ */
137
+ public function getCurrentDirection()
138
+ {
139
+ return $this->_getToolbarBlock()->getCurrentDirection();
140
+ }
141
+
142
+
143
+ /**
144
+ * Retrieve query model object
145
+ *
146
+ * @return Mage_CatalogSearch_Model_Query
147
+ */
148
+ public function getQuery()
149
+ {
150
+ return Mage::helper('catalogsearch')->getQuery();
151
+ }
152
+
153
+
154
+ /**
155
+ * Get Module Status depending on Module
156
+ *
157
+ * @return bool
158
+ */
159
+ public function getIsOnSearchPage()
160
+ {
161
+ $moduleName = Mage::app()->getRequest()->getModuleName();
162
+ $controllerName = Mage::app()->getRequest()->getControllerName();
163
+ $actionName = Mage::app()->getRequest()->getActionName();
164
+
165
+ if (($moduleName == 'catalogsearch' && $controllerName === 'result')
166
+ || ($moduleName == 'xmlconnect' && strpos($actionName, 'search') !== false)
167
+ ) {
168
+ return true;
169
+ }
170
+
171
+ return false;
172
+ }
173
+
174
+
175
+ /**
176
+ * Check if redirect to product page for single result
177
+ *
178
+ * @return bool
179
+ */
180
+ public function isRedirectForSingleResult()
181
+ {
182
+ return (bool) Mage::app()->getStore()->getConfig('factfinder/config/redirectOnSingleResult');
183
+ }
184
+
185
+
186
+ /**
187
+ * Redirect to product page
188
+ *
189
+ * @param \Mage_Catalog_Model_Product $product
190
+ */
191
+ public function redirectToProductPage(Mage_Catalog_Model_Product $product)
192
+ {
193
+ $response = Mage::app()->getResponse();
194
+ $response->setRedirect($product->getProductUrl());
195
+ $response->sendResponse();
196
+ exit;
197
+ }
198
+
199
+
200
+ }
app/code/community/FACTFinder/Core/Model/Autoloader.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * This class adds autoloading support for namespaces which are used by
16
+ * the new library.
17
+ *
18
+ * Class FACTFinder_Core_Model_Autoloader
19
+ *
20
+ * @category Mage
21
+ * @package FACTFinder_Core
22
+ * @author Flagbit Magento Team <magento@flagbit.de>
23
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ * @link http://www.flagbit.de
26
+ */
27
+ class FACTFinder_Core_Model_Autoloader
28
+ {
29
+
30
+ /**
31
+ * @var bool
32
+ */
33
+ protected static $registered = false;
34
+
35
+
36
+ /**
37
+ * Add autoloader class
38
+ *
39
+ * @param \Varien_Event_Observer $observer
40
+ *
41
+ * @return void
42
+ */
43
+ public function addAutoloader(Varien_Event_Observer $observer)
44
+ {
45
+ if (self::$registered) {
46
+ return;
47
+ }
48
+
49
+ spl_autoload_register(array($this, 'autoload'), false, true);
50
+ self::$registered = true;
51
+ }
52
+
53
+
54
+ /**
55
+ * Autoload method
56
+ *
57
+ * @param string $class
58
+ *
59
+ * @return void
60
+ */
61
+ public function autoload($class)
62
+ {
63
+ $classFile = str_replace('\\', '/', $class) . '.php';
64
+
65
+ if (strpos($classFile, '/') !== false) {
66
+ include $classFile;
67
+ }
68
+ }
69
+
70
+
71
+ }
app/code/community/FACTFinder/Core/Model/CatalogSearch/Layer.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Core_Model_CatalogSearch_Layer
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_CatalogSearch_Layer extends Mage_CatalogSearch_Model_Layer
25
+ {
26
+
27
+
28
+ /**
29
+ * Get current layer product collection
30
+ *
31
+ * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
32
+ */
33
+ public function getProductCollection()
34
+ {
35
+ if (!Mage::helper('factfinder')->isEnabled()) {
36
+ return parent::getProductCollection();
37
+ }
38
+
39
+ if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
40
+ $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
41
+ } else {
42
+ $collection = Mage::getResourceModel('factfinder/search_collection');
43
+ $this->prepareProductCollection($collection);
44
+ $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
45
+ }
46
+
47
+ return $collection;
48
+ }
49
+
50
+
51
+ }
app/code/community/FACTFinder/Core/Model/Export/Price.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * This class provides the Price export
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_Export_Price extends Mage_Core_Model_Resource_Db_Abstract
27
+ {
28
+
29
+ /**
30
+ * defines Export Columns
31
+ * @var array
32
+ */
33
+ protected $_exportColumns = array(
34
+ 'entity_id',
35
+ 'customer_group_id',
36
+ 'final_price',
37
+ 'min_price',
38
+ );
39
+
40
+ /**
41
+ * @var FACTFinder_Core_Model_File
42
+ */
43
+ protected $_file;
44
+
45
+ /**
46
+ * Resource initialization
47
+ *
48
+ * @return void
49
+ */
50
+ protected function _construct()
51
+ {
52
+ $this->_setResource('core');
53
+ }
54
+
55
+
56
+ /**
57
+ * Get file handler instance for store
58
+ *
59
+ * @param int $storeId
60
+ *
61
+ * @return FACTFinder_Core_Model_File
62
+ *
63
+ * @throws Exception
64
+ */
65
+ protected function _getFile($storeId)
66
+ {
67
+ if (!$this->_file) {
68
+ $dir = Mage::getBaseDir('var') . DS . 'factfinder';
69
+ $fileName = 'store_' . $storeId . '_price.csv';
70
+ $this->_file = Mage::getModel('factfinder/file');
71
+ $this->_file->open($dir, $fileName);
72
+ }
73
+
74
+ return $this->_file;
75
+ }
76
+
77
+
78
+ /**
79
+ * Write CSV Row
80
+ *
81
+ * @param array $data
82
+ * @param int $storeId
83
+ *
84
+ * @return bool
85
+ */
86
+ protected function _addCsvRow($data, $storeId = 0)
87
+ {
88
+ return $this->_getFile($storeId)->writeCsv($data, ';');
89
+ }
90
+
91
+
92
+ /**
93
+ * Export price data
94
+ * Write the data to file
95
+ *
96
+ * @param int $storeId Store Id
97
+ *
98
+ * @return $this
99
+ */
100
+ public function saveExport($storeId = null)
101
+ {
102
+ $this->_addCsvRow($this->_exportColumns, $storeId);
103
+
104
+ $page = 1;
105
+ $stocks = $this->_getPrices($storeId, $page);
106
+
107
+ while ($stocks) {
108
+ foreach ($stocks as $stock) {
109
+ $this->_addCsvRow($stock, $storeId);
110
+ }
111
+
112
+ $stocks = $this->_getPrices($storeId, $page++);
113
+ }
114
+
115
+ return $this->_getFile($storeId)->getPath();
116
+ }
117
+
118
+
119
+ /**
120
+ * Get prices from Price Index Table
121
+ *
122
+ * @param int $storeId Store ID
123
+ * @param int $part
124
+ * @param int $limit
125
+ *
126
+ * @return array
127
+ */
128
+ protected function _getPrices($storeId, $part = 1, $limit = 100)
129
+ {
130
+
131
+ $store = Mage::app()->getStore($storeId);
132
+ $select = $this->_getWriteAdapter()->select()
133
+ ->from(
134
+ array('e' => $this->getTable('catalog/product_index_price')),
135
+ $this->_exportColumns);
136
+
137
+ if ($storeId !== null) {
138
+ $select->where('e.website_id = ?', $store->getWebsiteId());
139
+ }
140
+
141
+ $select->limitPage($part, $limit)
142
+ ->order('e.entity_id');
143
+
144
+ return $this->_getWriteAdapter()->fetchAll($select);
145
+ }
146
+
147
+
148
+ }
app/code/community/FACTFinder/Core/Model/Export/Product.php ADDED
@@ -0,0 +1,1082 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * This class provides the Product export
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_Export_Product extends Mage_CatalogSearch_Model_Resource_Fulltext
27
+ {
28
+
29
+ /**
30
+ * Option ID to Value Mapping Array
31
+ * @var mixed
32
+ */
33
+ protected $_optionIdToValue = null;
34
+
35
+ /**
36
+ * Products to Category Path Mapping
37
+ *
38
+ * @var mixed
39
+ */
40
+ protected $_productsToCategoryPath = null;
41
+
42
+ /**
43
+ * Category Names by ID
44
+ * @var mixed
45
+ */
46
+ protected $_categoryNames = null;
47
+
48
+ /**
49
+ * export attribute codes
50
+ * @var mixed
51
+ */
52
+ protected $_exportAttributeCodes = null;
53
+
54
+ /**
55
+ * export attribute objects
56
+ * @var mixed
57
+ */
58
+ protected $_exportAttributes = null;
59
+
60
+ /**
61
+ * helper to generate the image urls
62
+ * @var Mage_Catalog_Helper_Image
63
+ */
64
+ protected $_imageHelper = null;
65
+
66
+ /**
67
+ * add CSV Row
68
+ *
69
+ * @param array $data
70
+ */
71
+ protected $_lines = array();
72
+
73
+ /**
74
+ * @var FACTFinder_Core_Model_File
75
+ */
76
+ protected $_file = null;
77
+
78
+ /**
79
+ * @var array
80
+ */
81
+ protected $_defaultHeader = array(
82
+ 'id',
83
+ 'parent_id',
84
+ 'sku',
85
+ 'category',
86
+ 'filterable_attributes',
87
+ 'searchable_attributes',
88
+ 'numerical_attributes',
89
+ );
90
+
91
+
92
+ /**
93
+ * Add row to csv
94
+ *
95
+ * @param array $data Array of data
96
+ * @param int $storeId
97
+ *
98
+ * @return FACTFinder_Core_Model_Export_Product
99
+ */
100
+ protected function _writeCsvRow($data, $storeId)
101
+ {
102
+ $this->_getFile($storeId)->writeCsv($data, ';');
103
+ return $this;
104
+ }
105
+
106
+
107
+ /**
108
+ * get Option Text by Option ID
109
+ *
110
+ * @param int $optionId Option ID
111
+ * @param int $storeId Store ID
112
+ *
113
+ * @return string
114
+ */
115
+ protected function _getAttributeOptionText($optionId, $storeId)
116
+ {
117
+ $value = '';
118
+ if (intval($optionId)) {
119
+ if ($this->_optionIdToValue === null) {
120
+ /** @var Mage_Eav_Model_Resource_Entity_Attribute_Option_Collection $optionCollection */
121
+ $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection');
122
+ $optionCollection->setStoreFilter($storeId);
123
+ $this->_optionIdToValue = array();
124
+ foreach ($optionCollection as $option) {
125
+ $this->_optionIdToValue[$option->getId()] = $option->getValue();
126
+ }
127
+ }
128
+
129
+ $value = isset($this->_optionIdToValue[$optionId]) ? $this->_optionIdToValue[$optionId] : '';
130
+ }
131
+
132
+ return $value;
133
+ }
134
+
135
+
136
+ /**
137
+ * Get CSV Header Array
138
+ *
139
+ * @param int $storeId
140
+ *
141
+ * @return array
142
+ */
143
+ protected function _getExportAttributes($storeId = 0)
144
+ {
145
+ if (!isset($this->_exportAttributeCodes[$storeId])) {
146
+ $headerDynamic = array();
147
+
148
+ $additionalColumns = array();
149
+ if (Mage::getStoreConfigFlag('factfinder/export/urls', $storeId)) {
150
+ $additionalColumns[] = 'image';
151
+ $additionalColumns[] = 'deeplink';
152
+ $this->_imageHelper = Mage::helper('catalog/image');
153
+ }
154
+
155
+ // get dynamic Attributes
156
+ foreach ($this->_getSearchableAttributes(null, 'system', $storeId) as $attribute) {
157
+ if (in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility'))) {
158
+ continue;
159
+ }
160
+
161
+ $headerDynamic[] = $attribute->getAttributeCode();
162
+ }
163
+
164
+ // compare dynamic with setup attributes
165
+ $headerSetup = Mage::helper('factfinder/backend')
166
+ ->unserializeFieldValue(Mage::getStoreConfig('factfinder/export/attributes', $storeId));
167
+ foreach ($headerDynamic as $code) {
168
+ if (in_array($code, $headerSetup)) {
169
+ continue;
170
+ }
171
+
172
+ $headerSetup[$code]['attribute'] = $code;
173
+ }
174
+
175
+ // remove default attributes from setup
176
+ foreach ($this->_defaultHeader as $code) {
177
+ if (array_key_exists($code, $headerSetup)) {
178
+ unset($headerSetup[$code]);
179
+ }
180
+ }
181
+
182
+ $this->_exportAttributeCodes[$storeId] = array_merge(
183
+ $this->_defaultHeader,
184
+ $additionalColumns,
185
+ array_keys($headerSetup)
186
+ );
187
+
188
+ // apply field limit as required by ff
189
+ if(count($this->_exportAttributeCodes[$storeId]) > 128) {
190
+ array_splice($this->_exportAttributeCodes[$storeId], 128);
191
+ }
192
+ }
193
+
194
+ return $this->_exportAttributeCodes[$storeId];
195
+ }
196
+
197
+
198
+ /**
199
+ * Pre-Generate all product exports for all stores
200
+ *
201
+ * @return array
202
+ */
203
+ public function saveAll()
204
+ {
205
+ $paths = array();
206
+ $stores = Mage::app()->getStores();
207
+ foreach ($stores as $id => $store) {
208
+ try {
209
+ $paths[] = $this->saveExport($id);
210
+ } catch (Exception $e) {
211
+ Mage::logException($e);
212
+ }
213
+ }
214
+
215
+ return $paths;
216
+ }
217
+
218
+
219
+ /**
220
+ * Generate product export for specific store
221
+ *
222
+ * @param int $storeId
223
+ *
224
+ * @return string
225
+ */
226
+ public function saveExport($storeId = 0)
227
+ {
228
+ $fileName = 'store_' . $storeId . '_product.csv';
229
+ $dir = Mage::getBaseDir('var') . DS . 'factfinder';
230
+
231
+ try {
232
+ $this->doExport($storeId);
233
+ } catch (Exception $e) {
234
+ Mage::throwException($e);
235
+ return '';
236
+ }
237
+
238
+ return $dir . DS . $fileName;
239
+ }
240
+
241
+
242
+ /**
243
+ * Get file handler instance for store
244
+ *
245
+ * @param int $storeId
246
+ *
247
+ * @return \FACTFinder_Core_Model_File
248
+ *
249
+ * @throws \Exception
250
+ */
251
+ protected function _getFile($storeId)
252
+ {
253
+ if (!isset($this->_file[$storeId])) {
254
+ $dir = Mage::getBaseDir('var') . DS . 'factfinder';
255
+
256
+ $fileName = 'store_' . $storeId . '_product.csv';
257
+
258
+ $this->_file[$storeId] = Mage::getModel('factfinder/file');
259
+
260
+ $this->_file[$storeId]->open($dir, $fileName);
261
+ }
262
+
263
+ return $this->_file[$storeId];
264
+ }
265
+
266
+
267
+ /**
268
+ * Export Product Data with Attributes
269
+ * direct Output as CSV
270
+ *
271
+ * @param int $storeId Store View Id
272
+ *
273
+ * @return array
274
+ */
275
+ public function doExport($storeId = null)
276
+ {
277
+ $this->_resetInternalState();
278
+
279
+ $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
280
+
281
+ $header = $this->_getExportAttributes($storeId);
282
+ $this->_writeCsvRow($header, $storeId);
283
+
284
+ // preparesearchable attributes
285
+ $staticFields = $this->_getStaticFields($storeId);
286
+
287
+ $dynamicFields = $this->_getDynamicFields();
288
+
289
+ // status and visibility filter
290
+ $visibility = $this->_getSearchableAttribute('visibility');
291
+ $status = $this->_getSearchableAttribute('status');
292
+ $visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
293
+ $statusVals = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();
294
+
295
+ $lastProductId = 0;
296
+ while (true) {
297
+ $products = $this->_getSearchableProducts($storeId, $staticFields, null, $lastProductId);
298
+ if (!$products) {
299
+ break;
300
+ }
301
+
302
+ $productAttributes = array();
303
+ $productRelations = array();
304
+ foreach ($products as $productData) {
305
+ $lastProductId = $productData['entity_id'];
306
+ $productAttributes[$productData['entity_id']] = $productData['entity_id'];
307
+ $productChildren = $this->_getProductChildIds($productData['entity_id'], $productData['type_id']);
308
+ $productRelations[$productData['entity_id']] = $productChildren;
309
+ if ($productChildren) {
310
+ foreach ($productChildren as $productChild) {
311
+ $productAttributes[$productChild['entity_id']] = $productChild;
312
+ }
313
+ }
314
+ }
315
+
316
+ $productAttributes = $this->_getProductAttributes($storeId, array_keys($productAttributes), $dynamicFields);
317
+ foreach ($products as $productData) {
318
+ if (!isset($productAttributes[$productData['entity_id']])) {
319
+ continue;
320
+ }
321
+
322
+ $productAttr = $productAttributes[$productData['entity_id']];
323
+
324
+ if (!isset($productAttr[$visibility->getId()])
325
+ || !in_array($productAttr[$visibility->getId()], $visibilityVals)
326
+ ) {
327
+ continue;
328
+ }
329
+
330
+ if (!isset($productAttr[$status->getId()]) || !in_array($productAttr[$status->getId()], $statusVals)) {
331
+ continue;
332
+ }
333
+
334
+ $categoryPath = $this->_getCategoryPath($productData['entity_id'], $storeId);
335
+
336
+ if ($categoryPath == '' && !$this->_isExportProductsWithoutCategories($storeId)) {
337
+ continue;
338
+ }
339
+
340
+ $productIndex = array(
341
+ $productData['entity_id'],
342
+ $productData[$idFieldName],
343
+ $productData['sku'],
344
+ $categoryPath,
345
+ $this->_formatAttributes('filterable', $productAttr, $storeId),
346
+ $this->_formatAttributes('searchable', $productAttr, $storeId),
347
+ $this->_formatAttributes('numerical', $productAttr, $storeId),
348
+ );
349
+
350
+ $productIndex = $this->_exportImageAndDeepLink($productIndex, $productData, $storeId);
351
+
352
+ $productIndex = $this->_getAttributesRowArray($productIndex, $productAttr, $storeId);
353
+
354
+ $this->_writeCsvRow($productIndex, $storeId);
355
+
356
+ $productChildren = $productRelations[$productData['entity_id']];
357
+ if ($productChildren) {
358
+ foreach ($productChildren as $productChild) {
359
+ if (isset($productAttributes[$productChild['entity_id']])) {
360
+
361
+ $productAttr = $productAttributes[$productChild['entity_id']];
362
+
363
+ $subProductIndex = array(
364
+ $productChild['entity_id'],
365
+ $productData[$idFieldName],
366
+ $productChild['sku'],
367
+ $this->_getCategoryPath($productData['entity_id'], $storeId),
368
+ $this->_formatAttributes('filterable', $productAttr, $storeId),
369
+ $this->_formatAttributes('searchable', $productAttr, $storeId),
370
+ $this->_formatAttributes('numerical', $productAttr, $storeId),
371
+ );
372
+ if ($this->_getIfExportImageAndDeeplink($storeId)) {
373
+ //dont need to add image and deeplink to child product, just add empty values
374
+ $subProductIndex[] = '';
375
+ $subProductIndex[] = '';
376
+ }
377
+
378
+ $subProductIndex = $this->_getAttributesRowArray(
379
+ $subProductIndex,
380
+ $productAttributes[$productChild['entity_id']],
381
+ $storeId
382
+ );
383
+
384
+ $this->_writeCsvRow($subProductIndex, $storeId);
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ Mage::dispatchEvent('factfinder_export_after', array(
392
+ 'store_id' => $storeId,
393
+ 'file' => $this->_getFile($storeId),
394
+ ));
395
+
396
+ return $this->_lines;
397
+ }
398
+
399
+
400
+ /**
401
+ * Resets the internal state of this export.
402
+ */
403
+ protected function _resetInternalState()
404
+ {
405
+ $this->_lines = array();
406
+ $this->_categoryNames = null;
407
+ $this->_productsToCategoryPath = null;
408
+ $this->_exportAttributes = null;
409
+ }
410
+
411
+ /**
412
+ * Get attributes by type
413
+ *
414
+ * @param string $type Possible values: filterable|searchable|numerical
415
+ * @param int $storeId
416
+ *
417
+ * @return array
418
+ */
419
+ protected function _getAttributesByType($type, $storeId)
420
+ {
421
+ switch ($type) {
422
+ case 'numerical':
423
+ $attributes = $this->_getSearchableAttributes('decimal', $type, $storeId);
424
+ break;
425
+ default:
426
+ $attributes = $this->_getSearchableAttributes(null, $type, $storeId);
427
+ }
428
+
429
+ return $attributes;
430
+ }
431
+
432
+
433
+ /**
434
+ * Format attributes for csv
435
+ *
436
+ * @param string $type
437
+ * @param array $values
438
+ * @param null|int $storeId
439
+ *
440
+ * @return string
441
+ */
442
+ protected function _formatAttributes($type, $values, $storeId = null)
443
+ {
444
+ $attributes = $this->_getAttributesByType($type, $storeId);
445
+
446
+ $returnArray = array();
447
+ $counter = 0;
448
+
449
+ foreach ($attributes as $attribute) {
450
+ $attributeValue = isset($values[$attribute->getId()]) ? $values[$attribute->getId()] : null;
451
+ if (!$attributeValue
452
+ || in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility', 'price'))
453
+ ) {
454
+ continue;
455
+ }
456
+
457
+ $attributeValues = $this->_getAttributeValue($attribute->getId(), $attributeValue, $storeId);
458
+
459
+ if (!is_array($attributeValues)) {
460
+ $attributeValues = array($attributeValues);
461
+ }
462
+
463
+ $attributeValues = $this->_filterAttributeValues($attributeValues);
464
+ foreach ($attributeValues as $attributeValue) {
465
+ $attributeValue = $this->_removeTags($attributeValue, $storeId);
466
+ if ($type == 'searchable') {
467
+ $returnArray[] = $attributeValue;
468
+ } else {
469
+ $attributeCode = $this->_removeTags($attribute->getAttributeCode(), $storeId);
470
+ $attributeValue = str_replace(array('|', '=', '#'), '', array($attributeCode, $attributeValue));
471
+ $returnArray[] = implode('=', $attributeValue);
472
+ }
473
+ }
474
+
475
+ // apply field limit as required by ff
476
+ $counter++;
477
+ if ($counter >= 1000) {
478
+ break;
479
+ }
480
+ }
481
+
482
+ $delimiter = ($type == 'searchable' ? ',' : '|');
483
+
484
+ return implode($delimiter, $returnArray);
485
+ }
486
+
487
+
488
+ /**
489
+ * Remove all empty values from array
490
+ *
491
+ * @param array $values
492
+ *
493
+ * @return array
494
+ */
495
+ protected function _filterAttributeValues($values)
496
+ {
497
+ // filter all empty values out
498
+ return array_filter($values, function ($value) {
499
+ return !empty($value);
500
+ });
501
+ }
502
+
503
+
504
+ /**
505
+ * Retrieve Searchable attributes
506
+ *
507
+ * @param string $backendType
508
+ * @param string $type possible Types: system, sortable, filterable, searchable
509
+ * @param int $storeId
510
+ *
511
+ * @return array
512
+ */
513
+ protected function _getSearchableAttributes($backendType = null, $type = null, $storeId = null)
514
+ {
515
+ if ($this->_searchableAttributes === null) {
516
+ $this->_searchableAttributes = array();
517
+ $entityType = $this->getEavConfig()->getEntityType('catalog_product');
518
+ $entity = $entityType->getEntity();
519
+
520
+ $userDefinedAttributes = array_keys(Mage::helper('factfinder/backend')
521
+ ->unserializeFieldValue(Mage::getStoreConfig('factfinder/export/attributes', $storeId)));
522
+
523
+ $whereCond = array(
524
+ $this->_getWriteAdapter()->quoteInto('additional_table.is_searchable=?', 1),
525
+ $this->_getWriteAdapter()->quoteInto('additional_table.is_filterable=?', 1),
526
+ $this->_getWriteAdapter()->quoteInto('additional_table.used_for_sort_by=?', 1),
527
+ $this->_getWriteAdapter()->quoteInto(
528
+ 'main_table.attribute_code IN(?)',
529
+ array_merge(array('status', 'visibility'), $userDefinedAttributes)
530
+ )
531
+ );
532
+
533
+ $select = $this->_getWriteAdapter()->select()
534
+ ->from(array('main_table' => $this->getTable('eav/attribute')))
535
+ ->join(
536
+ array('additional_table' => $this->getTable('catalog/eav_attribute')),
537
+ 'additional_table.attribute_id = main_table.attribute_id'
538
+ )
539
+ ->where('main_table.entity_type_id=?', $entityType->getEntityTypeId())
540
+ ->where(join(' OR ', $whereCond))
541
+ ->order('main_table.attribute_id', 'asc');
542
+
543
+ $attributesData = $this->_getWriteAdapter()->fetchAll($select);
544
+ $this->getEavConfig()->importAttributesData($entityType, $attributesData);
545
+
546
+ foreach ($attributesData as $attributeData) {
547
+ $attributeCode = $attributeData['attribute_code'];
548
+ $attribute = $this->getEavConfig()->getAttribute($entityType, $attributeCode);
549
+ $attribute->setEntity($entity);
550
+ $this->_searchableAttributes[$attribute->getId()] = $attribute;
551
+ }
552
+ }
553
+
554
+ if ($type !== null || $backendType !== null) {
555
+ $attributes = array();
556
+ foreach ($this->_searchableAttributes as $attribute) {
557
+ if ($backendType !== null
558
+ && $attribute->getBackendType() != $backendType
559
+ ) {
560
+ continue;
561
+ }
562
+
563
+ if ($this->_checkIfSkipAttribute($attribute, $type)) {
564
+ continue;
565
+ }
566
+
567
+ $attributes[$attribute->getId()] = $attribute;
568
+ }
569
+
570
+ return $attributes;
571
+ }
572
+
573
+ return $this->_searchableAttributes;
574
+ }
575
+
576
+
577
+ /**
578
+ * Get Category Path by Product ID
579
+ *
580
+ * @param int $productId
581
+ * @param int $storeId
582
+ *
583
+ * @return string
584
+ */
585
+ protected function _getCategoryPath($productId, $storeId = null)
586
+ {
587
+
588
+ if ($this->_categoryNames === null) {
589
+ $this->_loadCategoryNames($storeId);
590
+ }
591
+
592
+ if ($this->_productsToCategoryPath === null) {
593
+ $this->_loadCategoryPaths($storeId);
594
+ }
595
+
596
+ $value = '';
597
+ if (isset($this->_productsToCategoryPath[$productId])) {
598
+ $paths = explode(',', $this->_productsToCategoryPath[$productId]);
599
+ foreach ($paths as $path) {
600
+ $categoryIds = explode('/', $path);
601
+ $categoryIdsCount = count($categoryIds);
602
+ $categoryPath = '';
603
+ for ($i = 2; $i < $categoryIdsCount; $i++) {
604
+ if (!isset($this->_categoryNames[$categoryIds[$i]])) {
605
+ continue 2;
606
+ }
607
+
608
+ $categoryPath .= urlencode(trim($this->_categoryNames[$categoryIds[$i]])) . '/';
609
+ }
610
+
611
+ if ($categoryIdsCount > 2) {
612
+ $value .= rtrim($categoryPath, '/') . '|';
613
+ }
614
+ }
615
+
616
+ $value = trim($value, '|');
617
+ }
618
+
619
+ return $value;
620
+ }
621
+
622
+
623
+ /**
624
+ * Return all product children ids
625
+ *
626
+ * @param int $productId Product Entity Id
627
+ * @param string $typeId Super Product Link Type
628
+ *
629
+ * @return array
630
+ */
631
+ protected function _getProductChildIds($productId, $typeId)
632
+ {
633
+ $typeInstance = $this->_getProductTypeInstance($typeId);
634
+ $relation = $typeInstance->isComposite()
635
+ ? $typeInstance->getRelationInfo()
636
+ : false;
637
+
638
+ if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) {
639
+ $select = $this->_getReadAdapter()->select()
640
+ ->from(
641
+ array('main' => $this->getTable($relation->getTable())),
642
+ array($relation->getChildFieldName()))
643
+ ->join(
644
+ array('e' => $this->getTable('catalog/product')),
645
+ 'main.' . $relation->getChildFieldName() . '=e.entity_id',
646
+ array('entity_id', 'type_id', 'sku')
647
+ )
648
+ ->where("{$relation->getParentFieldName()}=?", $productId);
649
+ if ($relation->getWhere() !== null) {
650
+ $select->where($relation->getWhere());
651
+ }
652
+
653
+ return $this->_getReadAdapter()->fetchAll($select);
654
+ }
655
+
656
+ return null;
657
+ }
658
+
659
+
660
+ /**
661
+ * Retrieve attribute source value for search
662
+ * This method is mostly copied from Mage_CatalogSearch_Model_Resource_Fulltext,
663
+ * but it also retrieves attribute values from non-searchable/non-filterable attributes
664
+ *
665
+ * @param int $attributeId
666
+ * @param mixed $value
667
+ * @param int $storeId
668
+ *
669
+ * @return mixed
670
+ */
671
+ protected function _getAttributeValue($attributeId, $value, $storeId)
672
+ {
673
+ $attribute = $this->_getSearchableAttribute($attributeId);
674
+ if (!$attribute->getIsSearchable() && $attribute->getAttributeCode() == 'visibility') {
675
+ return $value;
676
+ }
677
+
678
+ if ($attribute->usesSource()) {
679
+ if (method_exists($this->_engine, 'allowAdvancedIndex') && $this->_engine->allowAdvancedIndex()) {
680
+ return $value;
681
+ }
682
+
683
+ $attribute->setStoreId($storeId);
684
+ $value = $attribute->getSource()->getOptionText($value);
685
+
686
+ if (empty($value)) {
687
+ $inputType = $attribute->getFrontend()->getInputType();
688
+ if ($inputType == 'select' || $inputType == 'multiselect') {
689
+ return null;
690
+ }
691
+ }
692
+ } elseif ($attribute->getBackendType() == 'datetime') {
693
+ $value = strtotime($value) * 1000; // Java.lang.System.currentTimeMillis()
694
+ } else {
695
+ $inputType = $attribute->getFrontend()->getInputType();
696
+ if ($inputType == 'price') {
697
+ $value = Mage::app()->getStore($storeId)->roundPrice($value);
698
+ }
699
+ }
700
+
701
+ return $value;
702
+ }
703
+
704
+
705
+ /**
706
+ * get Attribute Row Array
707
+ *
708
+ * @param array $dataArray Export row Array
709
+ * @param array $values Attributes Array
710
+ * @param int $storeId Store ID
711
+ *
712
+ * @return array
713
+ */
714
+ protected function _getAttributesRowArray($dataArray, $values, $storeId = null)
715
+ {
716
+ // get attributes objects assigned to their position at the export
717
+ if ($this->_exportAttributes == null) {
718
+ $this->_exportAttributes = array_fill(0, count($this->_getExportAttributes($storeId)), null);
719
+
720
+ $attributeCodes = array_flip($this->_getExportAttributes($storeId));
721
+ foreach ($this->_getSearchableAttributes() as $attribute) {
722
+ if (isset($attributeCodes[$attribute->getAttributeCode()])
723
+ && !in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility'))
724
+ ) {
725
+ $this->_exportAttributes[$attributeCodes[$attribute->getAttributeCode()]] = $attribute;
726
+ }
727
+ }
728
+ }
729
+
730
+ // fill dataArray with the values of the attributes that should be exported
731
+ foreach ($this->_exportAttributes as $pos => $attribute) {
732
+ if ($attribute != null) {
733
+ $value = isset($values[$attribute->getId()]) ? $values[$attribute->getId()] : null;
734
+ $value = $this->_getAttributeValue($attribute->getId(), $value, $storeId);
735
+ $value = $this->_removeTags($value, $storeId);
736
+ $dataArray[$pos] = $value;
737
+ } else if (!array_key_exists($pos, $dataArray)) {
738
+ // it's unlikely that an attribute exists in header but is not delivered by "getSearchableAttributes",
739
+ // but actually it might be a result of a broken database or something like that..
740
+ $dataArray[$pos] = null;
741
+ }
742
+ }
743
+
744
+ return $dataArray;
745
+ }
746
+
747
+
748
+ /**
749
+ * Check whether the attribute should be skipped
750
+ *
751
+ * @param Mage_Catalog_Model_Resource_EAV_Attribute $attribute
752
+ * @param string $type
753
+ *
754
+ * @return bool
755
+ */
756
+ protected function _checkIfSkipAttribute($attribute, $type)
757
+ {
758
+ $shouldSkip = false;
759
+ switch ($type) {
760
+ case "system":
761
+ if ($attribute->getIsUserDefined() && !$attribute->getUsedForSortBy()) {
762
+ $shouldSkip = true;
763
+ }
764
+ break;
765
+ case "sortable":
766
+ if (!$attribute->getUsedForSortBy()) {
767
+ $shouldSkip = true;
768
+ }
769
+ break;
770
+ case "filterable":
771
+ $shouldSkip = $this->_shouldSkipFilterableAttribute($attribute);
772
+ break;
773
+ case 'numerical':
774
+ $shouldSkip = $this->_shouldSkipNumericalAttribute($attribute);
775
+ break;
776
+ case "searchable":
777
+ $shouldSkip = $this->_shouldSkipSearchableAttribute($attribute);
778
+ break;
779
+ default:;
780
+ }
781
+
782
+ return $shouldSkip;
783
+ }
784
+
785
+
786
+ /**
787
+ * Check if we should skip searchable attribute
788
+ *
789
+ * @param Mage_Catalog_Model_Resource_EAV_Attribute $attribute
790
+ *
791
+ * @return bool
792
+ */
793
+ protected function _shouldSkipSearchableAttribute($attribute)
794
+ {
795
+ if (!$attribute->getIsUserDefined()
796
+ || !$attribute->getIsSearchable()
797
+ || in_array($attribute->getAttributeCode(), $this->_getExportAttributes())
798
+ || $attribute->getBackendType() === 'decimal'
799
+ ) {
800
+ return true;
801
+ }
802
+
803
+ return false;
804
+ }
805
+
806
+
807
+ /**
808
+ * Check if we should skip filterable attribute
809
+ *
810
+ * @param Mage_Catalog_Model_Resource_EAV_Attribute $attribute
811
+ *
812
+ * @return bool
813
+ */
814
+ protected function _shouldSkipFilterableAttribute($attribute)
815
+ {
816
+ if (!$attribute->getIsFilterableInSearch()
817
+ || in_array($attribute->getAttributeCode(), $this->_getExportAttributes())
818
+ || $attribute->getBackendType() === 'decimal'
819
+ ) {
820
+ return true;
821
+ }
822
+
823
+ return false;
824
+ }
825
+
826
+
827
+ /**
828
+ * Check if we should skip numerical attribute
829
+ *
830
+ * @param Mage_Catalog_Model_Resource_EAV_Attribute $attribute
831
+ *
832
+ * @return bool
833
+ */
834
+ protected function _shouldSkipNumericalAttribute($attribute)
835
+ {
836
+ if (!$attribute->getIsFilterableInSearch()
837
+ || in_array($attribute->getAttributeCode(), $this->_getExportAttributes())
838
+ || $attribute->getBackendType() != 'decimal'
839
+ ) {
840
+ return true;
841
+ }
842
+
843
+ return false;
844
+ }
845
+
846
+
847
+ /**
848
+ * Add image and deep link information to product row
849
+ *
850
+ * @param array $productIndex
851
+ * @param array $productData
852
+ * @param int $storeId
853
+ *
854
+ * @return array
855
+ */
856
+ protected function _exportImageAndDeepLink($productIndex, $productData, $storeId)
857
+ {
858
+ if ($this->_getIfExportImageAndDeeplink($storeId)) {
859
+ $baseAdminUrl = Mage::app()->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
860
+ if ($storeId !== null) {
861
+ $currentBaseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
862
+ }
863
+
864
+ $imageType = Mage::getStoreConfig('factfinder/export/suggest_image_type', $storeId);
865
+ $imageSize = Mage::getStoreConfig('factfinder/export/suggest_image_size', $storeId);
866
+
867
+ $product = Mage::getModel('catalog/product');
868
+ $product->setStoreId($storeId);
869
+ $product->load($productData['entity_id']);
870
+
871
+ $image = $this->_imageHelper->init($product, $imageType);
872
+ if (isset($imageSize) && $imageSize > 0) {
873
+ $image->resize($imageSize);
874
+ }
875
+
876
+ $image = (string) $image;
877
+
878
+ if ($storeId !== null) {
879
+ $image = str_replace($baseAdminUrl, $currentBaseUrl, $image);
880
+ }
881
+
882
+ $productIndex[] = $image;
883
+ $productIndex[] = $product->getProductUrl();
884
+
885
+ $product->clearInstance();
886
+ }
887
+
888
+ return $productIndex;
889
+ }
890
+
891
+
892
+ /**
893
+ * Check of image and deep links should be exported
894
+ *
895
+ * @param int $storeId
896
+ *
897
+ * @return bool
898
+ */
899
+ protected function _getIfExportImageAndDeeplink($storeId)
900
+ {
901
+ return Mage::getStoreConfigFlag('factfinder/export/urls', $storeId);
902
+ }
903
+
904
+
905
+ /**
906
+ * Get array of dynamic fields to use in csv
907
+ *
908
+ * @return array
909
+ */
910
+ protected function _getDynamicFields()
911
+ {
912
+ $dynamicFields = array();
913
+ foreach (array('int', 'varchar', 'text', 'decimal', 'datetime') as $type) {
914
+ $dynamicFields[$type] = array_keys($this->_getSearchableAttributes($type));
915
+ }
916
+
917
+ return $dynamicFields;
918
+ }
919
+
920
+
921
+ /**
922
+ * Get array of static fields to use in csv
923
+ *
924
+ * @param int $storeId
925
+ *
926
+ * @return array
927
+ */
928
+ protected function _getStaticFields($storeId)
929
+ {
930
+ $staticFields = array();
931
+ foreach ($this->_getSearchableAttributes('static', 'system', $storeId) as $attribute) {
932
+ $staticFields[] = $attribute->getAttributeCode();
933
+ }
934
+
935
+ return $staticFields;
936
+ }
937
+
938
+
939
+ /**
940
+ * Check if html tags and entities should be removed on export
941
+ *
942
+ * @param string $value
943
+ * @param int $storeId
944
+ *
945
+ * @return bool
946
+ */
947
+ protected function _removeTags($value, $storeId)
948
+ {
949
+ if (Mage::getStoreConfig('factfinder/export/remove_tags', $storeId)) {
950
+ // Add spaces before HTML Tags, so that strip_tags() does not join word
951
+ // which were in different block elements
952
+ // Additional spaces are not an issue, because they will be removed in the next step anyway
953
+ $value = preg_replace('/</u', ' <', $value);
954
+ $value = preg_replace("#\s+#siu", ' ', trim(strip_tags($value)));
955
+
956
+ // decode html entities
957
+ $value = html_entity_decode($value, null, 'UTF-8');
958
+
959
+ // remove rest html entities
960
+ $value = preg_replace("/&(?:[a-z\d]|#\d|#x[a-f\d]){2,8};/i", '', $value);
961
+ }
962
+
963
+ $value = addslashes($value);
964
+
965
+ return $value;
966
+ }
967
+
968
+
969
+ /**
970
+ * Check if products without categories should be exported
971
+ *
972
+ * @param int $storeId
973
+ *
974
+ * @return bool
975
+ */
976
+ protected function _isExportProductsWithoutCategories($storeId)
977
+ {
978
+ return Mage::getStoreConfig('factfinder/export/products_without_categories', $storeId);
979
+ }
980
+
981
+
982
+ /**
983
+ * Load category names to cache variable
984
+ *
985
+ * @param int $storeId
986
+ *
987
+ * @return $this
988
+ */
989
+ protected function _loadCategoryNames($storeId)
990
+ {
991
+ $nameAttribute = $this->_getCategoryNameAttribute();
992
+ $statusAttribute = $this->_getCategoryStatusAttribute();
993
+
994
+ $select = $this->_getReadAdapter()->select()
995
+ ->from(
996
+ array('main' => $nameAttribute->getBackendTable()),
997
+ array('entity_id', 'value')
998
+ )
999
+ ->join(
1000
+ array('e' => $statusAttribute->getBackendTable()),
1001
+ 'main.entity_id=e.entity_id AND (e.store_id = 0 OR e.store_id = ' . $storeId
1002
+ . ') AND e.attribute_id=' . $statusAttribute->getAttributeId(),
1003
+ null
1004
+ )
1005
+ ->where('main.attribute_id=?', $nameAttribute->getAttributeId())
1006
+ ->where('e.value=?', '1')
1007
+ ->where('main.store_id = 0 OR main.store_id = ?', $storeId);
1008
+
1009
+ $this->_categoryNames = $this->_getReadAdapter()->fetchPairs($select);
1010
+
1011
+ return $this;
1012
+ }
1013
+
1014
+
1015
+ /**
1016
+ * Get category name attribute model
1017
+ *
1018
+ * @return mixed
1019
+ */
1020
+ protected function _getCategoryNameAttribute()
1021
+ {
1022
+ $categoryAttributeCollection = Mage::getResourceModel('catalog/category_attribute_collection');
1023
+ $categoryAttributeCollection->addFieldToFilter('attribute_code', array('eq' => 'name'))
1024
+ ->getSelect()->limit(1);
1025
+
1026
+ return $categoryAttributeCollection->getFirstItem();
1027
+ }
1028
+
1029
+
1030
+ /**
1031
+ * Get category status attribute model (is_active)
1032
+ *
1033
+ * @return mixed
1034
+ */
1035
+ protected function _getCategoryStatusAttribute()
1036
+ {
1037
+ $categoryAttributeCollection = Mage::getResourceModel('catalog/category_attribute_collection');
1038
+ $categoryAttributeCollection->addFieldToFilter('attribute_code', array('eq' => 'is_active'))
1039
+ ->getSelect()->limit(1);
1040
+
1041
+ return $categoryAttributeCollection->getFirstItem();
1042
+ }
1043
+
1044
+
1045
+ /**
1046
+ * Load products to category paths
1047
+ *
1048
+ * @param int $storeId
1049
+ *
1050
+ * @return $this
1051
+ */
1052
+ protected function _loadCategoryPaths($storeId)
1053
+ {
1054
+ $select = $this->_getReadAdapter()->select()
1055
+ ->from(
1056
+ array('main' => $this->getTable('catalog/category_product_index')),
1057
+ array('product_id')
1058
+ )
1059
+ ->join(
1060
+ array('e' => $this->getTable('catalog/category')),
1061
+ 'main.category_id=e.entity_id',
1062
+ null
1063
+ )
1064
+ ->columns(array('e.path' => new Zend_Db_Expr('GROUP_CONCAT(e.path)')))
1065
+ ->where(
1066
+ 'main.visibility IN(?)',
1067
+ array(
1068
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
1069
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
1070
+ )
1071
+ )
1072
+ ->where('main.store_id = ?', $storeId)
1073
+ ->where('e.path LIKE \'1/' . Mage::app()->getStore($storeId)->getRootCategoryId() . '/%\'')
1074
+ ->group('main.product_id');
1075
+
1076
+ $this->_productsToCategoryPath = $this->_getReadAdapter()->fetchPairs($select);
1077
+
1078
+ return $this;
1079
+ }
1080
+
1081
+
1082
+ }
app/code/community/FACTFinder/Core/Model/Export/Stock.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * This class provides the stock export
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_Export_Stock extends Mage_Core_Model_Resource_Db_Abstract
27
+ {
28
+
29
+ /**
30
+ * defines Export Columns
31
+ *
32
+ * @var array
33
+ */
34
+ protected $_exportColumns = array(
35
+ 'product_id',
36
+ 'qty',
37
+ 'stock_status'
38
+ );
39
+
40
+ /**
41
+ * @var FACTFinder_Core_Model_File
42
+ */
43
+ protected $_file;
44
+
45
+
46
+ /**
47
+ * Resource initialization
48
+ *
49
+ * @return void
50
+ */
51
+ protected function _construct()
52
+ {
53
+ $this->_setResource('core');
54
+ }
55
+
56
+
57
+ /**
58
+ * Get file handler instance for store
59
+ *
60
+ * @param int $storeId
61
+ *
62
+ * @return FACTFinder_Core_Model_File
63
+ *
64
+ * @throws Exception
65
+ */
66
+ protected function _getFile($storeId)
67
+ {
68
+ if (!$this->_file) {
69
+ $dir = Mage::getBaseDir('var') . DS . 'factfinder';
70
+ $fileName = 'store_' . $storeId . '_stock.csv';
71
+ $this->_file = Mage::getModel('factfinder/file');
72
+ $this->_file->open($dir, $fileName);
73
+ }
74
+
75
+ return $this->_file;
76
+ }
77
+
78
+
79
+ /**
80
+ * Write CSV Row
81
+ *
82
+ * @param array $data
83
+ * @param int $storeId
84
+ *
85
+ * @return bool
86
+ */
87
+ protected function _addCsvRow($data, $storeId = 0)
88
+ {
89
+ return $this->_getFile($storeId)->writeCsv($data, ';');
90
+ }
91
+
92
+
93
+ /**
94
+ * export Stock Data
95
+ * Write the data to file
96
+ *
97
+ * @param int $storeId Store Id
98
+ *
99
+ * @return $this
100
+ */
101
+ public function saveExport($storeId = null)
102
+ {
103
+ $this->_addCsvRow($this->_exportColumns, $storeId);
104
+
105
+ $page = 1;
106
+ $stocks = $this->_getStockData($storeId, $page);
107
+
108
+ while ($stocks) {
109
+ foreach($stocks as $stock){
110
+ $this->_addCsvRow($stock, $storeId);
111
+ }
112
+
113
+ $stocks = $this->_getStockData($storeId, $page++);
114
+ }
115
+
116
+ return $this->_getFile($storeId)->getPath();
117
+ }
118
+
119
+
120
+ /**
121
+ * Get Stocks from Stock Index Table
122
+ *
123
+ * @param int $storeId Store ID
124
+ * @param int $part
125
+ * @param int $limit
126
+ *
127
+ * @return array
128
+ */
129
+ protected function _getStockData($storeId, $part = 1, $limit = 100)
130
+ {
131
+
132
+ $store = Mage::app()->getStore($storeId);
133
+ $select = $this->_getWriteAdapter()->select()
134
+ ->from(
135
+ array('e' => $this->getTable('cataloginventory/stock_status')),
136
+ $this->_exportColumns
137
+ );
138
+
139
+ if ($storeId !== null) {
140
+ $select->where('e.website_id = ?', $store->getWebsiteId());
141
+ }
142
+
143
+ $select->limitPage($part, $limit)
144
+ ->order('e.product_id');
145
+
146
+ return $this->_getWriteAdapter()->fetchAll($select);
147
+ }
148
+
149
+
150
+ }
app/code/community/FACTFinder/Core/Model/Facade.php ADDED
@@ -0,0 +1,708 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ require_once BP . DS . 'lib' . DS . 'FACTFinder' . DS . 'Loader.php';
15
+ use FACTFinder\Loader as FF;
16
+
17
+ /**
18
+ * Class FACTFinder_Core_Model_Facade
19
+ *
20
+ * Implements a facade for accessing the FF library
21
+ *
22
+ * @category Mage
23
+ * @package FACTFinder_Core
24
+ * @author Flagbit Magento Team <magento@flagbit.de>
25
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
26
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
27
+ * @link http://www.flagbit.de
28
+ */
29
+ class FACTFinder_Core_Model_Facade
30
+ {
31
+
32
+ /**
33
+ * Two-dimensional array of FACT-Finder adapters
34
+ * First-dimension key corresponds to type
35
+ * Second-dimension key corresponds to channel
36
+ *
37
+ * @var array of FACTFinder\Adapter\AbstractAdapter
38
+ */
39
+ protected $_adapters = array();
40
+
41
+ /**
42
+ * @var FACTFinderCustom_Configuration
43
+ */
44
+ protected $_config = null;
45
+
46
+ /**
47
+ * @var \FACTFinder\Core\ConfigurationInterface
48
+ */
49
+ protected $_dic = null;
50
+
51
+ /**
52
+ * @var \FACTFinder\Data\SearchParameters
53
+ */
54
+ protected $_paramsParser = null;
55
+
56
+ /**
57
+ * @var \FACTFinder\Core\Server\UrlBuilder
58
+ */
59
+ protected $_urlBuilder = null;
60
+
61
+ /**
62
+ * logger object to log all module internals
63
+ *
64
+ * @var \FACTFinder\Util\LoggerInterface
65
+ */
66
+ protected $_logger = null;
67
+
68
+ /**
69
+ * map between known adapters and its state based on its parameters
70
+ *
71
+ * @var array
72
+ */
73
+ protected $_paramHashes = array();
74
+
75
+ /**
76
+ * flag if stacktrace was already logged
77
+ *
78
+ * @var null
79
+ */
80
+ protected $_stackTraceLogged = null;
81
+
82
+
83
+ /**
84
+ * Class constructor
85
+ *
86
+ * @param mixed $arg
87
+ * @param mixed $config
88
+ */
89
+ public function __construct($arg = null, $config = null)
90
+ {
91
+ if ($arg === null || !($arg instanceof FACTFinder\Util\LoggerInterface)) {
92
+ $arg = Mage::helper('factfinder/debug');
93
+ }
94
+
95
+ FF::disableCustomClasses();
96
+
97
+ $dic = FF::getInstance('Util\Pimple');
98
+
99
+ $dic['loggerClass'] = function ($c) use ($arg) {
100
+ return $arg;
101
+ };
102
+
103
+ $dic['configuration'] = function ($c) use ($config) {
104
+ return new FACTFinderCustom_Configuration($config);
105
+ };
106
+
107
+ $dic['request'] = $dic->factory(function ($c) {
108
+ return $c['requestFactory']->getRequest();
109
+ });
110
+
111
+ $dic['requestFactory'] = function ($c) {
112
+ return FF::getInstance(
113
+ 'Core\Server\MultiCurlRequestFactory',
114
+ $c['loggerClass'],
115
+ $c['configuration'],
116
+ $c['requestParser']->getRequestParameters()
117
+ );
118
+ };
119
+
120
+ $dic['clientUrlBuilder'] = function ($c) {
121
+ return FF::getInstance(
122
+ 'Core\Client\UrlBuilder',
123
+ $c['loggerClass'],
124
+ $c['configuration'],
125
+ $c['requestParser'],
126
+ $c['encodingConverter']
127
+ );
128
+ };
129
+
130
+ $dic['serverUrlBuilder'] = function ($c) {
131
+ return FF::getInstance(
132
+ 'Core\Server\UrlBuilder',
133
+ $c['loggerClass'],
134
+ $c['configuration']
135
+ );
136
+ };
137
+
138
+ $dic['requestParser'] = function ($c) {
139
+ return FF::getInstance(
140
+ 'Core\Client\RequestParser',
141
+ $c['loggerClass'],
142
+ $c['configuration'],
143
+ $c['encodingConverter']
144
+ );
145
+ };
146
+
147
+ $dic['encodingConverter'] = function ($c) {
148
+ if (extension_loaded('iconv')) {
149
+ $type = 'Core\IConvEncodingConverter';
150
+ } elseif(function_exists('utf8_encode')
151
+ && function_exists('utf8_decode')
152
+ ) {
153
+ $type = 'Core\Utf8EncodingConverter';
154
+ } else {
155
+ throw new \Exception('No encoding conversion available.');
156
+ }
157
+
158
+ return FF::getInstance(
159
+ $type,
160
+ $c['loggerClass'],
161
+ $c['configuration']
162
+ );
163
+ };
164
+
165
+ $this->_dic = $dic;
166
+
167
+ $this->_logger = $arg;
168
+ }
169
+
170
+
171
+ /**
172
+ * Retrieve an instance of search adapter
173
+ *
174
+ * @param string $channel
175
+ *
176
+ * @return \FACTFinder\Adapter\Search
177
+ */
178
+ public function getSearchAdapter($channel = null)
179
+ {
180
+ return $this->_getAdapter("search", $channel);
181
+ }
182
+
183
+
184
+ /**
185
+ *
186
+ * Get an instance of compare adapter
187
+ *
188
+ * @param string $channel
189
+ *
190
+ * @return \FACTFinder\Adapter\Compare
191
+ */
192
+ public function getCompareAdapter($channel = null)
193
+ {
194
+ return $this->_getAdapter("compare", $channel);
195
+ }
196
+
197
+
198
+ /**
199
+ * Get an instance of import adapter
200
+ *
201
+ * @param string $channel
202
+ *
203
+ * @return \FACTFinder\Adapter\Import
204
+ */
205
+ public function getImportAdapter($channel = null)
206
+ {
207
+ return $this->_getAdapter("import", $channel);
208
+ }
209
+
210
+
211
+ /**
212
+ * Get an instance of similar records adapter
213
+ *
214
+ * @param string $channel
215
+ *
216
+ * @return \FACTFinder\Adapter\SimilarRecords
217
+ */
218
+ public function getSimilarRecordsAdapter($channel = null)
219
+ {
220
+ return $this->_getAdapter("similarRecords", $channel);
221
+ }
222
+
223
+
224
+ /**
225
+ * Configure search adapter
226
+ *
227
+ * @param array $params
228
+ * @param string $channel
229
+ * @param int $id
230
+ *
231
+ * @return void
232
+ */
233
+ public function configureSearchAdapter($params, $channel = null, $id = null)
234
+ {
235
+ $this->_configureAdapter($params, "search", $channel, $id);
236
+ }
237
+
238
+
239
+ /**
240
+ * Configure compare adapter
241
+ *
242
+ * @param array $params
243
+ * @param string $channel
244
+ * @param int $id
245
+ *
246
+ * @return void
247
+ */
248
+ public function configureCompareAdapter($params, $channel = null, $id = null)
249
+ {
250
+ $this->_configureAdapter($params, "compare", $channel, $id);
251
+ }
252
+
253
+
254
+ /**
255
+ * Configure import adapter
256
+ *
257
+ * @param array $params
258
+ * @param string $channel
259
+ * @param int $id
260
+ *
261
+ * @return void
262
+ */
263
+ public function configureImportAdapter($params, $channel = null, $id = null)
264
+ {
265
+ $this->_configureAdapter($params, "import", $channel, $id);
266
+ }
267
+
268
+
269
+ /**
270
+ * Configure similar records adapter
271
+ *
272
+ * @param array $params
273
+ * @param string $channel
274
+ * @param int $id
275
+ *
276
+ * @return void
277
+ */
278
+ public function configureSimilarRecordsAdapter($params, $channel = null, $id = null)
279
+ {
280
+ $this->_configureAdapter($params, "similarRecords", $channel, $id);
281
+ }
282
+
283
+
284
+ /**
285
+ * Configure adapter
286
+ *
287
+ * @param array $params
288
+ * @param string $type
289
+ * @param string $channel
290
+ * @param int $id
291
+ *
292
+ * @return void
293
+ */
294
+ protected function _configureAdapter($params, $type, $channel = null, $id = null)
295
+ {
296
+ $adapterId = $this->_getAdapterIdentifier($type, $channel, $id);
297
+ $this->_paramHashes[$adapterId] = $this->_createParametersHash($params);
298
+
299
+ foreach ($params as $key => $value) {
300
+ $this->_dic['requestParser']->getClientRequestParameters()->set($key, $value);
301
+ $this->_dic['requestParser']->getRequestParameters()->set($key, $value);
302
+ }
303
+ }
304
+
305
+
306
+ /**
307
+ * Returns the hash that identifies a certain combination of parameters.
308
+ * It represents the current parameter state of the adapter specified by $type, $channel and $id
309
+ *
310
+ * @param string $type (any adapter type)
311
+ * @param string $channel (default: null => default channel)
312
+ * @param int $id (default: null => no special id)
313
+ *
314
+ * @return string
315
+ */
316
+ protected function _getParametersHash($type, $channel = null, $id = null)
317
+ {
318
+ $returnValue = '';
319
+ $adapterId = $this->_getAdapterIdentifier($type, $channel, $id);
320
+ if (array_key_exists($adapterId, $this->_paramHashes)) {
321
+ $returnValue = $this->_paramHashes[$adapterId];
322
+ }
323
+
324
+ return $returnValue;
325
+ }
326
+
327
+
328
+ /**
329
+ * Create hash for an array of params
330
+ *
331
+ * @param array $params
332
+ *
333
+ * @return string
334
+ */
335
+ private function _createParametersHash($params)
336
+ {
337
+ $returnValue = '';
338
+ if ($params) {
339
+ ksort($params);
340
+ $returnValue = md5(http_build_query($params));
341
+ }
342
+
343
+ return $returnValue;
344
+ }
345
+
346
+
347
+ /**
348
+ * Get identifying hash for each adapter based on type, channel and id
349
+ *
350
+ * @param string $type
351
+ * @param string $channel (default: null)
352
+ * @param int $id (default: null)
353
+ *
354
+ * @return string
355
+ */
356
+ protected function _getAdapterIdentifier($type, $channel = null, $id = null)
357
+ {
358
+ $args = func_get_args();
359
+
360
+ return implode('_', $args);
361
+ }
362
+
363
+
364
+ /**
365
+ * Get an instance of adapter
366
+ *
367
+ * @param string $type
368
+ * @param string $channel (default: null)
369
+ * @param int $id (default: null)
370
+ *
371
+ * @return \FACTFinder\Adapter\AbstractAdapter
372
+ */
373
+ protected function _getAdapter($type, $channel = null, $id = null)
374
+ {
375
+ $hashKey = $this->_getAdapterIdentifier($type, $channel, $id);
376
+
377
+ // get the channel after calculating the adapter identifier
378
+ if (!$channel) {
379
+ $channel = $this->getConfiguration()->getChannel();
380
+ }
381
+
382
+ if (!isset($this->_adapters[$hashKey][$channel])) {
383
+ $this->_adapters[$hashKey][$channel] = FF::getInstance(
384
+ 'Adapter\\' . ucfirst($type),
385
+ $this->_dic['loggerClass'],
386
+ $this->_dic['configuration'],
387
+ $this->_dic['request'],
388
+ $this->_dic['clientUrlBuilder']
389
+ );
390
+ }
391
+
392
+ return $this->_adapters[$hashKey][$channel];
393
+ }
394
+
395
+
396
+ /**
397
+ * Get current facade configuration
398
+ *
399
+ * @return FACTFinderCustom_Configuration
400
+ */
401
+ public function getConfiguration()
402
+ {
403
+ if ($this->_config == null) {
404
+ $this->_config = $this->_dic['configuration'];
405
+ }
406
+
407
+ return $this->_config;
408
+ }
409
+
410
+
411
+ /**
412
+ * Set facade configuration
413
+ *
414
+ * @param array $configArray
415
+ *
416
+ * @return void
417
+ */
418
+ public function setConfiguration($configArray)
419
+ {
420
+ $this->_config = new FACTFinderCustom_Configuration($configArray);
421
+ }
422
+
423
+
424
+ /**
425
+ * Set store id
426
+ *
427
+ * @param int $storeId
428
+ *
429
+ * @return FACTFinder_Core_Model_Facade
430
+ */
431
+ public function setStoreId($storeId)
432
+ {
433
+ $this->getConfiguration()->setStoreId($storeId);
434
+
435
+ return $this;
436
+ }
437
+
438
+
439
+ /**
440
+ * Get url for accessing web-interface
441
+ *
442
+ * @return string
443
+ */
444
+ public function getManagementUrl()
445
+ {
446
+ return $this->_getUrlBuilder()
447
+ ->getNonAuthenticationUrl('Management.ff', $this->_dic['requestParser']->getRequestParameters());
448
+ }
449
+
450
+
451
+ /**
452
+ * Get url builder object
453
+ *
454
+ * @return \FACTFinder\Core\Server\UrlBuilder
455
+ */
456
+ protected function _getUrlBuilder()
457
+ {
458
+ if ($this->_urlBuilder === null) {
459
+ $this->_urlBuilder = $this->_dic['serverUrlBuilder'];
460
+ }
461
+
462
+ return $this->_urlBuilder;
463
+ }
464
+
465
+
466
+ /**
467
+ * Get after search navigation object
468
+ *
469
+ * @param string $channel
470
+ * @param int $id
471
+ *
472
+ * @return \FACTFinder\Data\AfterSearchNavigation
473
+ */
474
+ public function getAfterSearchNavigation($channel = null, $id = null)
475
+ {
476
+ $result = $this->_getFactFinderObject("search", "getAfterSearchNavigation", $channel, $id);
477
+
478
+ $this->_checkStackTrace($channel, $id);
479
+
480
+ return $result;
481
+ }
482
+
483
+
484
+ /**
485
+ * Get search error message
486
+ *
487
+ * @param string|null $channel
488
+ * @param int|null $id
489
+ *
490
+ * @return string|null
491
+ */
492
+ public function getSearchError($channel = null, $id = null)
493
+ {
494
+ return $this->_getFactFinderObject("search", "getError", $channel, $id);
495
+ }
496
+
497
+
498
+ /**
499
+ * Retrieve search parameters from request
500
+ *
501
+ * @return \FACTFinder\Data\SearchParameters
502
+ */
503
+ public function getSearchParams()
504
+ {
505
+ if ($this->_paramsParser == null) {
506
+ $this->_paramsParser = FF::getInstance(
507
+ 'Data\SearchParameters',
508
+ $this->_dic['requestParser']->getRequestParameters()
509
+ );
510
+ }
511
+
512
+ return $this->_paramsParser;
513
+ }
514
+
515
+
516
+ /**
517
+ * Get raw client parameters
518
+ *
519
+ * @return \FACTFinder\Util\Parameters
520
+ */
521
+ public function getClientRequestParams()
522
+ {
523
+ return $this->_dic['requestParser']->getClientRequestParameters();
524
+ }
525
+
526
+
527
+ /**
528
+ * Get search result object
529
+ *
530
+ * @param string|null $channel
531
+ * @param int|null $id
532
+ *
533
+ * @return \FACTFinder\Data\Result
534
+ */
535
+ public function getSearchResult($channel = null, $id = null)
536
+ {
537
+ $result = $this->_getFactFinderObject("search", "getResult", $channel, $id);
538
+
539
+ $this->_checkStackTrace($channel, $id);
540
+
541
+ return $result;
542
+ }
543
+
544
+
545
+ /**
546
+ * Get search stacktrace string
547
+ *
548
+ * @param string|null $channel
549
+ * @param int|null $id
550
+ *
551
+ * @return string
552
+ */
553
+ public function getSearchStackTrace($channel = null, $id = null)
554
+ {
555
+ return $this->_getFactFinderObject("search", "getStackTrace", $channel, $id);
556
+ }
557
+
558
+
559
+ /**
560
+ * Get search status string
561
+ *
562
+ * @param string $channel
563
+ * @param int $id
564
+ *
565
+ * @return string
566
+ */
567
+ public function getSearchStatus($channel = null, $id = null)
568
+ {
569
+ return $this->_getFactFinderObject("search", "getStatus", $channel, $id);
570
+ }
571
+
572
+
573
+ /**
574
+ * Get search campaigns
575
+ *
576
+ * @param string $channel
577
+ * @param int $id
578
+ *
579
+ * @return \FACTFinder\Data\CampaignIterator|null
580
+ */
581
+ public function getSearchCampaigns($channel = null, $id = null)
582
+ {
583
+ return $this->_getFactFinderObject("search", "getCampaigns", $channel, $id);
584
+ }
585
+
586
+
587
+ /**
588
+ * Get an object of a specified type
589
+ * Returns null in case of an error
590
+ *
591
+ * @param string $type
592
+ * @param string $objectGetter
593
+ * @param string $channel
594
+ * @param int $id
595
+ *
596
+ * @return Object|null
597
+ */
598
+ protected function _getFactFinderObject($type, $objectGetter, $channel = null, $id = null)
599
+ {
600
+ $data = null;
601
+
602
+ try {
603
+ $adapter = $this->_getAdapter($type, $channel, $id);
604
+ $data = $adapter->$objectGetter();
605
+ } catch (Exception $e) {
606
+ Mage::logException($e);
607
+ }
608
+
609
+ return $data;
610
+ }
611
+
612
+
613
+ /**
614
+ * @return \FACTFinder\Core\ConfigurationInterface|object
615
+ */
616
+ public function getDic()
617
+ {
618
+ return $this->_dic;
619
+ }
620
+
621
+
622
+ /**
623
+ * Create a new results object
624
+ *
625
+ * @param array $records
626
+ * @param string $refKey
627
+ * @param int $foundRecordsCount
628
+ *
629
+ * @return \FACTFinder\Data\Result
630
+ */
631
+ public function getNewResultObject($records, $refKey, $foundRecordsCount)
632
+ {
633
+ return FF::getInstance(
634
+ 'Data\Result',
635
+ $records,
636
+ $refKey,
637
+ $foundRecordsCount
638
+ );
639
+ }
640
+
641
+
642
+ /**
643
+ * Get paging object (collection)
644
+ *
645
+ * @param string $channel
646
+ * @param int $id
647
+ *
648
+ * @return \FACTFinder\Data\Paging
649
+ */
650
+ public function getPaging($channel = null, $id = null)
651
+ {
652
+ $result = $this->_getFactFinderObject('search', 'getPaging', $channel, $id);
653
+
654
+ $this->_checkStackTrace($channel, $id);
655
+
656
+ return $result;
657
+ }
658
+
659
+
660
+ /**
661
+ * Get sorting object (collection)
662
+ *
663
+ * @param string $channel
664
+ * @param int $id
665
+ *
666
+ * @return \FACTFinder\Data\Sorting
667
+ */
668
+ public function getSorting($channel = null, $id = null)
669
+ {
670
+ return $this->_getFactFinderObject('search', 'getSorting', $channel, $id);
671
+ }
672
+
673
+ /**
674
+ * Log stack trace if there is one in result
675
+ */
676
+ protected function _checkStackTrace($channel, $id)
677
+ {
678
+ if($this->_stackTraceLogged) {
679
+ return;
680
+ }
681
+
682
+ $helper = Mage::helper('factfinder/debug');
683
+ if ($helper->isDebugMode()
684
+ && $this->getSearchError($channel, $id)
685
+ && $this->getSearchStackTrace($channel, $id)
686
+ ) {
687
+ $helper->trace($this->getSearchStackTrace($channel, $id));
688
+ $this->_stackTraceLogged = true;
689
+ }
690
+ }
691
+
692
+
693
+ /**
694
+ * Trigger data import on FF side
695
+ *
696
+ * @param null|string $channel
697
+ *
698
+ * @return SimpleXMLElement
699
+ */
700
+ public function triggerDataImport($channel = null)
701
+ {
702
+ $this->configureImportAdapter(array('channel' => $channel));
703
+
704
+ return $this->getImportAdapter($channel)->triggerDataImport(true);
705
+ }
706
+
707
+
708
+ }
app/code/community/FACTFinder/Core/Model/File.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_File
25
+ {
26
+
27
+ /**
28
+ * @var Varien_Io_File
29
+ */
30
+ protected $_file;
31
+
32
+ /**
33
+ * @var string
34
+ */
35
+ protected $_path;
36
+
37
+ /**
38
+ * Class constructor
39
+ */
40
+ public function __construct()
41
+ {
42
+ $this->_file = new Varien_Io_File();
43
+ }
44
+
45
+
46
+ /**
47
+ * Make directory
48
+ *
49
+ * @param string $dir
50
+ * @param int $mode
51
+ * @param bool $recursive
52
+ *
53
+ * @return bool
54
+ */
55
+ public function mkdir($dir, $mode = 0777, $recursive=true)
56
+ {
57
+ return $this->_file->mkdir($dir, $mode, $recursive);
58
+ }
59
+
60
+
61
+ /**
62
+ * Open file for writing
63
+ *
64
+ * @param string $dir
65
+ * @param string $filename
66
+ *
67
+ * @return bool
68
+ *
69
+ * @throws \Exception
70
+ */
71
+ public function open($dir, $filename)
72
+ {
73
+ $this->_path = $dir . DS . $filename;
74
+
75
+ $this->_file->mkdir($dir);
76
+ $this->_file->open(array('path' => $dir));
77
+
78
+ return $this->_file->streamOpen($filename);
79
+ }
80
+
81
+
82
+ /**
83
+ * Write a line to the file
84
+ *
85
+ * @param string $str
86
+ *
87
+ * @return bool
88
+ */
89
+ public function write($str)
90
+ {
91
+ return $this->_file->streamWrite($str);
92
+ }
93
+
94
+ /**
95
+ * Write array as comma separated values to file
96
+ *
97
+ * @param array $data
98
+ * @param string $delimiter
99
+ * @param string $enclosure
100
+ * @return bool|int
101
+ */
102
+ public function writeCsv(array $data, $delimiter = ',', $enclosure = '"')
103
+ {
104
+ return $this->_file->streamWriteCsv($data, $delimiter, $enclosure);
105
+ }
106
+
107
+ /**
108
+ * Returns path of current file
109
+ *
110
+ * @return string
111
+ */
112
+ public function getPath()
113
+ {
114
+ return $this->_path;
115
+ }
116
+
117
+ /**
118
+ * Close stream
119
+ *
120
+ * @return bool
121
+ */
122
+ public function close()
123
+ {
124
+ return $this->_file->streamClose();
125
+ }
126
+
127
+
128
+ /**
129
+ * Class destructor
130
+ */
131
+ public function __destruct()
132
+ {
133
+ $this->close();
134
+ }
135
+ }
app/code/community/FACTFinder/Core/Model/Handler/Abstract.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Abstract handler class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ abstract class FACTFinder_Core_Model_Handler_Abstract
25
+ {
26
+
27
+ /**
28
+ * Facade model name
29
+ *
30
+ * @var string
31
+ */
32
+ protected $_facadeModel = 'factfinder/facade';
33
+
34
+ /**
35
+ * @var FACTFinder_Core_Model_Facade
36
+ **/
37
+ protected $_facade;
38
+
39
+
40
+ /**
41
+ * Class constructor
42
+ */
43
+ public function __construct()
44
+ {
45
+ $this->_configureFacade();
46
+ }
47
+
48
+
49
+ /**
50
+ * Implement this method to set up any adapters the handler will need later on.
51
+ * WARNING: You will always have to configure...() the adapter once, even if you do not set any parameters.
52
+ * This will register the adapter with the Facade and lets it query all data in parallel.
53
+ *
54
+ * @return void
55
+ */
56
+ abstract protected function _configureFacade();
57
+
58
+
59
+ /**
60
+ * Get an instance of FACT-Finder facade
61
+ *
62
+ * @return FACTFinder_Core_Model_Facade
63
+ */
64
+ protected function _getFacade()
65
+ {
66
+ if ($this->_facade === null) {
67
+ $this->_facade = Mage::getSingleton($this->_facadeModel);
68
+ }
69
+
70
+ return $this->_facade;
71
+ }
72
+
73
+
74
+ }
app/code/community/FACTFinder/Core/Model/Handler/Search.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Search handler class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+
25
+ use FACTFinder\Loader as FF;
26
+
27
+ class FACTFinder_Core_Model_Handler_Search extends FACTFinder_Core_Model_Handler_Abstract
28
+ {
29
+
30
+ const SEARCH_STATUS_REGISTRY_KEY = 'ff_search_status';
31
+
32
+ protected $_searchResult;
33
+ protected $_searchResultCount;
34
+ protected $_paging;
35
+
36
+
37
+ /**
38
+ * Set configuration params to the search adapter
39
+ *
40
+ * @return void
41
+ */
42
+ protected function _configureFacade()
43
+ {
44
+ $params = $this->_collectParams();
45
+
46
+ $this->_getFacade()->configureSearchAdapter($params);
47
+ }
48
+
49
+
50
+ /**
51
+ * Prepare all request parameters for the primary search adapter
52
+ *
53
+ * @return array
54
+ */
55
+ protected function _collectParams()
56
+ {
57
+ // search Helper
58
+ $helper = Mage::helper('factfinder/search');
59
+ $_request = Mage::app()->getRequest();
60
+ $requestParams = $this->_getFacade()->getClientRequestParams();
61
+ $searchParams = $this->_getFacade()->getSearchParams();
62
+ $params = array();
63
+
64
+ if (Mage::helper('factfinder')->isInternal()) {
65
+ $params['log'] = 'internal';
66
+ }
67
+
68
+ switch ($_request->getModuleName()) {
69
+ case "xmlconnect":
70
+ $_query = $helper->getQueryText();
71
+ $params['idsOnly'] = FF::getSingleton('configuration')->getIdsOnly() ? 'true' : 'false';
72
+ $params['query'] = $_query;
73
+
74
+ $count = $searchParams->getProductsPerPage() ? $searchParams->getProductsPerPage() : 0;
75
+ if ($count > 0) {
76
+ $params['productsPerPage'] = $count;
77
+ $params['page'] = $searchParams->getCurrentPage();
78
+ }
79
+
80
+ // todo: make this work
81
+ // add Sorting Param
82
+ foreach ($searchParams->getSortings() as $key => $value) {
83
+ if (substr($key, 0, 6) == 'order_') {
84
+ $key = substr($key, 6);
85
+ if (!in_array($key, array('position', 'relevance'))) {
86
+ $params['sort' . $key] = $value;
87
+ }
88
+ }
89
+ }
90
+
91
+ break;
92
+ case "catalogsearch":
93
+ default:
94
+ // add Default Params
95
+ $params['idsOnly'] = $this->_getFacade()->getConfiguration()->getIdsOnly() ? 'true' : 'false';
96
+ $params['productsPerPage'] = $helper->getPageLimit();
97
+
98
+ if ($_request->getModuleName() == 'catalogsearch') {
99
+ $params['query'] = $helper->getQueryText();
100
+ }
101
+
102
+ $params['page'] = $helper->getCurrentPage();
103
+
104
+ if ($seoPath = Mage::app()->getRequest()->getParam('seoPath')) {
105
+ $params['seoPath'] = $seoPath;
106
+ }
107
+
108
+ // add Sorting Param, but only if it was set explicitly via url
109
+ if (isset($requestParams['order'])
110
+ && $helper->getCurrentOrder()
111
+ && $helper->getCurrentDirection()
112
+ && $helper->getCurrentOrder() != 'position'
113
+ && $helper->getCurrentOrder() != 'relevance'
114
+ ) {
115
+ $params['sort' . $helper->getCurrentOrder()] = $helper->getCurrentDirection();
116
+ }
117
+ }
118
+
119
+ if (Mage::helper('factfinder/debug')->isDebugMode()) {
120
+ $params['verbose'] = 'true';
121
+ }
122
+
123
+ if(Mage::getStoreConfigFlag('factfinder/config/personalization')) {
124
+ $params['sid'] = Mage::helper('factfinder_tracking')->getSessionId();
125
+ }
126
+
127
+ return $params;
128
+ }
129
+
130
+
131
+ /**
132
+ * Get number of found products
133
+ *
134
+ * @return int|null
135
+ */
136
+ public function getSearchResultCount()
137
+ {
138
+ if ($this->_searchResultCount === null) {
139
+ if (!$this->isSearchHasResult()) {
140
+ Mage::helper('factfinder')->performFallbackRedirect();
141
+ }
142
+
143
+ $result = $this->_getFacade()->getSearchResult();
144
+ if ($result instanceof \FACTFinder\Data\Result) {
145
+ $this->_searchResultCount = $result->getFoundRecordsCount();
146
+ }
147
+
148
+ if ($this->_searchResultCount === null) {
149
+ $this->_searchResultCount = 0;
150
+ }
151
+ }
152
+
153
+ return $this->_searchResultCount;
154
+ }
155
+
156
+
157
+ /**
158
+ * Get array of found products
159
+ *
160
+ * @return array
161
+ */
162
+ public function getSearchResult()
163
+ {
164
+ if ($this->_searchResult === null) {
165
+ if (!$this->isSearchHasResult()) {
166
+ Mage::helper('factfinder')->performFallbackRedirect();
167
+ }
168
+
169
+ $this->_searchResult = array();
170
+
171
+ $result = $this->_getFacade()->getSearchResult();
172
+ if ($result instanceof \FACTFinder\Data\Result) {
173
+ foreach ($result as $record) {
174
+ if (isset($this->_searchResult[$record->getId()])) {
175
+ continue;
176
+ }
177
+
178
+ $this->_searchResult[$record->getId()] = new Varien_Object(
179
+ array(
180
+ 'similarity' => $record->getSimilarity(),
181
+ 'position' => $record->getPosition(),
182
+ 'original_position' => $record->getField('__ORIG_POSITION__')
183
+ )
184
+ );
185
+ }
186
+ }
187
+ }
188
+
189
+ return $this->_searchResult;
190
+ }
191
+
192
+
193
+ /**
194
+ * Get pagination object from FF
195
+ *
196
+ * @return \FACTFinder\Data\Paging
197
+ */
198
+ public function getPaging()
199
+ {
200
+ if (!$this->isSearchHasResult()) {
201
+ return null;
202
+ }
203
+
204
+ return $this->_getFacade()->getPaging();
205
+ }
206
+
207
+
208
+ /**
209
+ * Get sortings object from FF
210
+ *
211
+ * @return \FACTFinder\Data\Sorting|null
212
+ */
213
+ public function getSorting()
214
+ {
215
+ if (!$this->isSearchHasResult()) {
216
+ return null;
217
+ }
218
+
219
+ return $this->_getFacade()->getSorting();
220
+ }
221
+
222
+
223
+ /**
224
+ * Return ArticleNumberSearchStatus
225
+ *
226
+ * @return \FACTFinder\Data\ArticleNumberSearchStatus
227
+ */
228
+ public function getArticleNumberStatus()
229
+ {
230
+ $status = \FACTFinder\Data\ArticleNumberSearchStatus::IsNoArticleNumberResultFound();
231
+
232
+ if (!$this->isSearchHasResult()) {
233
+ return $status;
234
+ }
235
+
236
+ try {
237
+ $status = $this->_getFacade()->getSearchAdapter()->getArticleNumberStatus();
238
+ } catch (Exception $e) {
239
+ Mage::logException($e);
240
+ }
241
+
242
+ return $status;
243
+ }
244
+
245
+
246
+ /**
247
+ * Get search status object
248
+ *
249
+ * @return \FACTFinder\Data\SearchStatus
250
+ */
251
+ public function getSearchStatus()
252
+ {
253
+ $status = Mage::registry(self::SEARCH_STATUS_REGISTRY_KEY);
254
+ if ($status === null) {
255
+ $status = \FACTFinder\Data\SearchStatus::NoResult();
256
+ try {
257
+ $status = $this->_getFacade()->getSearchAdapter()->getStatus();
258
+ } catch (Exception $e) {
259
+ Mage::logException($e);
260
+ }
261
+
262
+ Mage::register(self::SEARCH_STATUS_REGISTRY_KEY, $status, true);
263
+ }
264
+
265
+ return $status;
266
+ }
267
+
268
+
269
+ /**
270
+ * Check if the seach request contains results
271
+ *
272
+ * @return bool
273
+ */
274
+ public function isSearchHasResult()
275
+ {
276
+ return $this->getSearchStatus() !== \FACTFinder\Data\SearchStatus::NoResult();
277
+ }
278
+
279
+
280
+ }
app/code/community/FACTFinder/Core/Model/Handler/Status.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ use FACTFinder\Loader as FF;
15
+
16
+ // Possible status/error codes
17
+
18
+ define('FFE_OK', 16180000);
19
+
20
+ define('FFE_CURL_ERROR', 16181000); // add the result of curl_errno() to this
21
+
22
+ define('FFE_HTTP_ERROR', 16182000); // add the HTTP code to this
23
+ define('FFE_WRONG_CONTEXT', 16182404); //
24
+
25
+ define('FFE_FACT_FINDER_ERROR', 16183000); // unspecified exception from FF; contact support
26
+ define('FFE_CHANNEL_DOES_NOT_EXIST', 16183001);
27
+ define('FFE_WRONG_CREDENTIALS', 16183002);
28
+ define('FFE_SERVER_TIME_MISMATCH', 16183003); // server time is not consistent with FF's server time
29
+
30
+ /**
31
+ * Status handler
32
+ *
33
+ * Checks whether the configuration is working
34
+ *
35
+ * @category Mage
36
+ * @package FACTFinder_Core
37
+ * @author Flagbit Magento Team <magento@flagbit.de>
38
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
39
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
40
+ * @link http://www.flagbit.de
41
+ */
42
+ class FACTFinder_Core_Model_Handler_Status extends FACTFinder_Core_Model_Handler_Search
43
+ {
44
+
45
+ /**
46
+ * Array of error messages
47
+ *
48
+ * @var array
49
+ */
50
+ protected $_errorMessages = array();
51
+
52
+ /**
53
+ * Helper instance
54
+ *
55
+ * @var FACTFinder_Core_Helper_Data
56
+ */
57
+ protected $_helper;
58
+
59
+ /**
60
+ * Secondary channels array
61
+ *
62
+ * @var array
63
+ */
64
+ protected $_secondaryChannels;
65
+
66
+ /**
67
+ * Mapping of error codes and messages
68
+ *
69
+ * @var array
70
+ */
71
+ protected $_errorMapping = array(
72
+ FFE_WRONG_CONTEXT => 'FACT-Finder not found on server. Please check your context setting.',
73
+ FFE_CHANNEL_DOES_NOT_EXIST => 'Channel does not exist or the specified user does not have sufficient rights.',
74
+ FFE_WRONG_CREDENTIALS
75
+ => 'Could not log into FACT-Finder with the given settings. Please check username, password, prefix and postfix.',
76
+ FFE_SERVER_TIME_MISMATCH
77
+ => 'Your server\'s clock does not agree with FACT-Finder\'s. Please make sure your clock is set correctly.',
78
+ FFE_CURL_ERROR => 'Could not establish HTTP connection. cURL Error Code: %s',
79
+ FFE_HTTP_ERROR => 'Could not contact FACT-Finder. HTTP Status Code: %s',
80
+ FFE_FACT_FINDER_ERROR => 'There is a problem with FACT-Finder. Please contact FACT-Finder Support.',
81
+ );
82
+
83
+
84
+ /**
85
+ * prepares all request parameters for the primary search adapter
86
+ *
87
+ * @return array
88
+ */
89
+ protected function _collectParams()
90
+ {
91
+ $this->_secondaryChannels = $this->_getFacade()->getConfiguration()->getSecondaryChannels();
92
+
93
+ $params = array();
94
+ $params['channel'] = $this->_getFacade()->getConfiguration()->getChannel();
95
+ $params['query'] = 'FACT-Finder Version';
96
+ $params['productsPerPage'] = '1';
97
+ $params['verbose'] = 'true';
98
+
99
+ return $params;
100
+ }
101
+
102
+
103
+ /**
104
+ * Check status of fact-finder connection
105
+ *
106
+ * @return bool
107
+ */
108
+ public function checkStatus()
109
+ {
110
+ $statusOkay = true;
111
+ $this->_errorMessage = array();
112
+
113
+ $primaryStatus = $this->getStatusCode();
114
+ if ($primaryStatus !== FFE_OK) {
115
+ $this->_errorMessages[] = $this->_retrieveErrorMessage($primaryStatus);
116
+ $statusOkay = false;
117
+ }
118
+
119
+ foreach ($this->_secondaryChannels as $channel) {
120
+ $secondaryStatus = $this->getStatusCode($channel);
121
+ if ($secondaryStatus !== FFE_OK) {
122
+ $this->_errorMessages[] = $this->_retrieveErrorMessage($secondaryStatus, $channel);
123
+ $statusOkay = false;
124
+ }
125
+ }
126
+
127
+ return $statusOkay;
128
+ }
129
+
130
+
131
+ /**
132
+ * Retrieve full error message
133
+ *
134
+ * @param int $statusCode
135
+ * @param string $channel
136
+ *
137
+ * @return string
138
+ */
139
+ protected function _retrieveErrorMessage($statusCode, $channel = null)
140
+ {
141
+ $helper = $this->_getHelper();
142
+ if ($channel === null) {
143
+ $errorMessage = $helper->__('Error in Primary Channel') . ': ';
144
+ } else {
145
+ $errorMessage = $helper->__('Error in Channel') . ' "' . $channel . '": ';
146
+ }
147
+
148
+ if (isset ($this->_errorMapping[$statusCode])) {
149
+ $errorMessage .= $helper->__($this->_errorMapping[$statusCode]);
150
+ }
151
+
152
+ $codeType = (int) floor($statusCode / 1000) * 1000;
153
+
154
+ if (isset ($this->_errorMapping[$codeType])) {
155
+ $errorMessage .= $helper->__($this->_errorMapping[$statusCode], $statusCode - $codeType);
156
+ } else {
157
+ $errorMessage .= $helper->__('An unknown error has occurred. Please contact FACT-Finder Support.');
158
+ }
159
+
160
+ return $errorMessage;
161
+ }
162
+
163
+
164
+ /**
165
+ * Get helper instance
166
+ *
167
+ * @return FACTFinder_Core_Helper_Data
168
+ */
169
+ protected function _getHelper()
170
+ {
171
+ if ($this->_helper === null) {
172
+ $this->_helper = Mage::helper('factfinder');
173
+ }
174
+
175
+ return $this->_helper;
176
+ }
177
+
178
+
179
+ /**
180
+ * Get error messages
181
+ *
182
+ * @return array
183
+ */
184
+ public function getErrorMessages()
185
+ {
186
+ return $this->_errorMessages;
187
+ }
188
+
189
+
190
+ /**
191
+ * Get Fact-finder version number from adapter
192
+ *
193
+ * @return int
194
+ */
195
+ public function getVersionNumber()
196
+ {
197
+ $resultCount = $this->_getFacade()->getSearchAdapter()->getResult()->getFoundRecordsCount();
198
+
199
+ return intval(substr($resultCount, 0, 2));
200
+ }
201
+
202
+
203
+ /**
204
+ * Get full version string
205
+ *
206
+ * @return string
207
+ */
208
+ public function getVersionString()
209
+ {
210
+ $versionNumber = '' . $this->getVersionNumber();
211
+
212
+ return $versionNumber[0] . '.' . $versionNumber[1];
213
+ }
214
+
215
+
216
+ /**
217
+ * Get status code from ff adapter
218
+ *
219
+ * @param string|null $channel
220
+ *
221
+ * @return int
222
+ */
223
+ public function getStatusCode($channel = null)
224
+ {
225
+ /* start @todo solve this problem without reflection */
226
+ $params = array('channel' => $channel);
227
+ $this->_getFacade()->configureSearchAdapter($params, $channel);
228
+ $resultObj = $this->_getFacade()->getSearchAdapter($channel);
229
+
230
+ $reflectionClass = new ReflectionClass('FACTFinder\Adapter\Search');
231
+ $property = $reflectionClass->getProperty('request');
232
+ $property->setAccessible(true);
233
+
234
+ $request = $property->getValue($resultObj);
235
+ $response = $request->getResponse();
236
+
237
+ $reflectionClass = new ReflectionClass('FACTFinder\Core\Server\Response');
238
+ $httpCode = $reflectionClass->getProperty('httpCode');
239
+ $httpCode->setAccessible(true);
240
+ $connectionError = $reflectionClass->getProperty('connectionError');
241
+ $connectionError->setAccessible(true);
242
+ $connectionErrorCode = $reflectionClass->getProperty('connectionErrorCode');
243
+ $connectionErrorCode->setAccessible(true);
244
+ /* end */
245
+
246
+ $curlErrno = $connectionErrorCode->getValue($response);
247
+
248
+ switch ($curlErrno) {
249
+ case 0: // no cURL error!
250
+ break;
251
+ default:
252
+ return FFE_CURL_ERROR + $connectionError->getValue($response);
253
+ }
254
+
255
+ // cURL was able to connect to the server, check HTTP Code next
256
+
257
+ $httpCode = intval($httpCode->getValue($response));
258
+
259
+ switch ($httpCode) {
260
+ case 200: // success!
261
+ return FFE_OK;
262
+ case 500: // server error, check error output
263
+ break;
264
+ default:
265
+ return FFE_HTTP_ERROR + $httpCode;
266
+ }
267
+
268
+ $stackTrace = $this->_getFacade()->getSearchAdapter()->getStackTrace();
269
+ Mage::helper('factfinder/debug')->trace($stackTrace);
270
+ preg_match('/^(.+?):?\s/', $stackTrace, $matches);
271
+ $ffException = $matches[1];
272
+
273
+ switch ($ffException) {
274
+ case 'de.factfinder.security.exception.ChannelDoesNotExistException':
275
+ return FFE_CHANNEL_DOES_NOT_EXIST;
276
+ case 'de.factfinder.security.exception.WrongUserPasswordException':
277
+ return FFE_WRONG_CREDENTIALS;
278
+ case 'de.factfinder.security.exception.PasswordExpiredException':
279
+ return FFE_SERVER_TIME_MISMATCH;
280
+ case 'de.factfinder.jni.FactFinderException':
281
+ default:
282
+ return FFE_FACT_FINDER_ERROR;
283
+ }
284
+ }
285
+
286
+
287
+ }
app/code/community/FACTFinder/Core/Model/Observer.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Observer class
16
+ *
17
+ * Used to replace search engine, search layer, manage modules availability
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_Observer
27
+ {
28
+ const SEARCH_ENGINE = 'factfinder/search_engine';
29
+ const DEFAULT_SEARCH_ENGINE = 'catalogsearch/fulltext_engine';
30
+ const REDIRECT_ALREADY_CHECKED_FLAG = 'factifinder_single_result_redirect_flag';
31
+
32
+
33
+ /**
34
+ * Replace the config entry with search engine when enabling the module
35
+ *
36
+ * @param Varien_Object $observer
37
+ *
38
+ * @return void
39
+ */
40
+ public function setSearchEngine($observer)
41
+ {
42
+ $request = $observer->getControllerAction()->getRequest();
43
+ if ($request->getParam('section') != 'factfinder') {
44
+ return;
45
+ }
46
+
47
+ $groups = $request->getPost('groups');
48
+ $website = $request->getParam('website');
49
+ $store = $request->getParam('store');
50
+
51
+ if (is_array($groups['search'])
52
+ && is_array($groups['search']['fields'])
53
+ && is_array($groups['search']['fields']['enabled'])
54
+ && isset($groups['search']['fields']['enabled']['value'])
55
+ ) {
56
+ $value = $groups['search']['fields']['enabled']['value'];
57
+ } elseif ($store) {
58
+ $value = Mage::app()->getWebsite($website)->getConfig('factfinder/search/enabled');
59
+ } else {
60
+ $value = (string) Mage::getConfig()->getNode('default/factfinder/search/enabled');
61
+ }
62
+
63
+ if (empty($value)) {
64
+ Mage::app()->getConfig()->saveConfig('catalog/search/engine', self::DEFAULT_SEARCH_ENGINE);
65
+ return;
66
+ }
67
+
68
+ $errors = Mage::helper('factfinder/backend')->checkConfigData($groups['search']['fields']);
69
+
70
+ if (!empty($errors)) {
71
+ foreach ($errors as $error) {
72
+ Mage::getSingleton('adminhtml/session')->addError($error);
73
+ }
74
+
75
+ Mage::app()->getConfig()->saveConfig('catalog/search/engine', self::DEFAULT_SEARCH_ENGINE);
76
+ Mage::app()->getConfig()->saveConfig('factfinder/search/enabled', 0);
77
+ } else {
78
+ Mage::app()->getConfig()->saveConfig('catalog/search/engine', self::SEARCH_ENGINE);
79
+ }
80
+
81
+ // this also helps with module managing
82
+ Mage::app()->cleanCache();
83
+ if (Mage::helper('core')->isModuleEnabled('Enterprise_PageCache')) {
84
+ Enterprise_PageCache_Model_Cache::getCacheInstance()
85
+ ->clean(Enterprise_PageCache_Model_Processor::CACHE_TAG);
86
+ }
87
+ }
88
+
89
+
90
+ /**
91
+ * Reset current search layer for further use in the block
92
+ *
93
+ * @param Varien_Object $observer
94
+ *
95
+ * @return void
96
+ */
97
+ public function resetCurrentSearchLayer($observer)
98
+ {
99
+ if (!Mage::helper('factfinder')->isEnabled()) {
100
+ return;
101
+ }
102
+
103
+ Mage::register('current_layer', Mage::getSingleton('factfinder/catalogSearch_layer'));
104
+ }
105
+
106
+
107
+ /**
108
+ * Remove all layered navigation filters on search page
109
+ *
110
+ * @param Varien_Object $observer
111
+ *
112
+ * @return void
113
+ */
114
+ public function removeLayerFilters($observer)
115
+ {
116
+ if (!Mage::helper('factfinder')->isEnabled()) {
117
+ return;
118
+ }
119
+
120
+ $block = $observer->getBlock();
121
+
122
+ if (!$block instanceof Mage_CatalogSearch_Block_Layer) {
123
+ return;
124
+ }
125
+
126
+ $block->unsetChildren();
127
+ $block->setData('_filterable_attributes', array());
128
+
129
+ if(Mage::helper('core')->isModuleEnabled('Mage_ConfigurableSwatches')) {
130
+ $this->_disableConfigurableSwatchesEvent();
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Disable ConfigurableSwatches observer logic
136
+ */
137
+ protected function _disableConfigurableSwatchesEvent()
138
+ {
139
+ // Initialize reflection for Mage::app()->_events
140
+ $mageApp = new ReflectionObject(Mage::app());
141
+ $_events = $mageApp->getProperty('_events');
142
+ $_events->setAccessible(true);
143
+
144
+ // Disable ConfigurableSwatch Event
145
+ Mage::getConfig()->getEventConfig('frontend','controller_action_layout_generate_blocks_after')
146
+ ->setNode('/observers/configurableswatches/type', 'disabled');
147
+
148
+ $_events->setAccessible(false);
149
+ }
150
+
151
+
152
+ /**
153
+ * Manage modules availability
154
+ * Enable them only if they were enable in core configuration
155
+ *
156
+ * @param Varien_Object $observer
157
+ *
158
+ * @return void
159
+ */
160
+ public function manageModules($observer)
161
+ {
162
+ $config = Mage::getConfig();
163
+ $modules = $config->getNode('modules');
164
+
165
+ $isConfigUpdated = false;
166
+ foreach ($modules->children() as $module => $data) {
167
+ if (strpos($module, 'FACTFinder_') === 0 && $module !== 'FACTFinder_Core') {
168
+ $configName = strtolower(str_replace('FACTFinder_', '', $module));
169
+ $isActivated = Mage::helper('factfinder')->isModuleActivated($configName);
170
+
171
+ $currentState = (string) $config->getNode("modules/{$module}/active");
172
+ if ((bool) $currentState === (bool) $isActivated) {
173
+ continue;
174
+ }
175
+
176
+ $isConfigUpdated = Mage::helper('factfinder')->updateModuleState($module, $isActivated);
177
+ }
178
+ }
179
+
180
+ if ($isConfigUpdated) {
181
+ Mage::app()->cleanCache();
182
+ }
183
+ }
184
+
185
+
186
+ /**
187
+ * Redirect to product page on single result
188
+ *
189
+ * @param Varien_Object $observer
190
+ *
191
+ * @return void
192
+ */
193
+ public function handleSingleProductRedirect($observer)
194
+ {
195
+ if (!Mage::helper('factfinder/search')->getIsOnSearchPage()) {
196
+ return;
197
+ }
198
+
199
+ $block = Mage::app()->getLayout()->getBlock('search_result_list');
200
+ if (!($block instanceof Mage_Catalog_Block_Product_List)) {
201
+ return;
202
+ }
203
+
204
+ if (Mage::registry(self::REDIRECT_ALREADY_CHECKED_FLAG)
205
+ || Mage::app()->getRequest()->getParam('p', 0) > 1
206
+ ) {
207
+ return;
208
+ }
209
+
210
+ Mage::register(self::REDIRECT_ALREADY_CHECKED_FLAG, true, true);
211
+
212
+ if ($this->shouldRedirectToProduct()) {
213
+ $collection = $block->getLoadedProductCollection();
214
+ $product = $collection->getFirstItem();
215
+ Mage::dispatchEvent('factfinder_redirect_on_single_result_before',
216
+ array('product' => $product)
217
+ );
218
+
219
+ /** @var FACTFinder_Core_Helper_Search $helper */
220
+ $helper = Mage::helper('factfinder/search');
221
+ $helper->redirectToProductPage($product);
222
+ }
223
+ }
224
+
225
+
226
+ /**
227
+ * @return bool
228
+ */
229
+ protected function shouldRedirectToProduct()
230
+ {
231
+ /** @var FACTFinder_Core_Helper_Search $helper */
232
+ $helper = Mage::helper('factfinder/search');
233
+ if (!$helper->getIsOnSearchPage() || !$helper->isRedirectForSingleResult()) {
234
+ return false;
235
+ }
236
+
237
+ /** @var FACTFinder_Core_Model_Handler_Search $searchHandler */
238
+ $searchHandler = Mage::getSingleton('factfinder/handler_search');
239
+
240
+ $articleNumberStatus = $searchHandler->getArticleNumberStatus();
241
+
242
+ if ($articleNumberStatus === \FACTFinder\Data\ArticleNumberSearchStatus::IsArticleNumberResultFound()
243
+ && $searchHandler->getSearchResultCount() == 1
244
+ ) {
245
+ return true;
246
+ }
247
+
248
+ return false;
249
+ }
250
+
251
+
252
+ /**
253
+ * @param Varien_Object $observer
254
+ *
255
+ * @return void
256
+ */
257
+ public function triggerImportAfterExport($observer)
258
+ {
259
+ $helper = Mage::helper('factfinder');
260
+ $storeId = $observer->getStoreId();
261
+ if ($helper->isEnabled() && $helper->isImportTriggerEnabled($storeId)) {
262
+ foreach ($helper->getStoreChannels($storeId) as $channel) {
263
+ $facade = Mage::getModel('factfinder/facade');
264
+ $facade->triggerDataImport($channel);
265
+ }
266
+ }
267
+ }
268
+
269
+
270
+ }
app/code/community/FACTFinder/Core/Model/Resource/Search/Collection.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Product collection that uses the ids taken from ff
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_Resource_Search_Collection extends Mage_Catalog_Model_Resource_Product_Collection
25
+ {
26
+
27
+
28
+ /**
29
+ * Get collection size
30
+ *
31
+ * @return int
32
+ */
33
+ public function getSize()
34
+ {
35
+ return $this->_getSearchHandler()->getSearchResultCount();
36
+ }
37
+
38
+
39
+ /**
40
+ * Get FACT-Finder Facade
41
+ *
42
+ * @return FACTFinder_Core_Model_Handler_Search
43
+ */
44
+ protected function _getSearchHandler()
45
+ {
46
+ return Mage::getSingleton('factfinder/handler_search');
47
+ }
48
+
49
+
50
+ /**
51
+ * Add search query filter
52
+ *
53
+ * @param Mage_CatalogSearch_Model_Query $query
54
+ *
55
+ * @return FACTFinder_Core_Model_Resource_Search_Collection
56
+ */
57
+ public function addSearchFilter($query)
58
+ {
59
+ return $this;
60
+ }
61
+
62
+
63
+ /**
64
+ * Set Order field
65
+ *
66
+ * @param string $attribute
67
+ * @param string $dir
68
+ *
69
+ * @return FACTFinder_Core_Model_Resource_Search_Collection
70
+ */
71
+ public function setOrder($attribute, $dir = 'desc')
72
+ {
73
+ return $this;
74
+ }
75
+
76
+
77
+ /**
78
+ * Load entities records into items
79
+ *
80
+ * @param bool $printQuery
81
+ * @param bool $logQuery
82
+ *
83
+ * @throws Exception
84
+ * @throws Mage_Core_Exception
85
+ *
86
+ * @return Mage_Eav_Model_Entity_Collection_Abstract
87
+ */
88
+ public function _loadEntities($printQuery = false, $logQuery = false)
89
+ {
90
+ // get product IDs from Fact-Finder
91
+ $productIds = $this->_getSearchHandler()->getSearchResult();
92
+
93
+ if (!empty($productIds)) {
94
+ $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
95
+
96
+ // add Filter to Query
97
+ $this->addFieldToFilter(
98
+ $idFieldName,
99
+ array('in' => array_keys($productIds))
100
+ );
101
+
102
+ $this->_pageSize = null;
103
+
104
+ $this->getSelect()->reset(Zend_Db_Select::LIMIT_COUNT);
105
+ $this->getSelect()->reset(Zend_Db_Select::LIMIT_OFFSET);
106
+
107
+ $this->printLogQuery($printQuery, $logQuery);
108
+ Mage::helper('factfinder/debug')->log('Search SQL Query: ' . $this->getSelect()->__toString());
109
+
110
+ try {
111
+ $rows = $this->_fetchAll($this->getSelect());
112
+ } catch (Exception $e) {
113
+ Mage::printException($e, $this->getSelect());
114
+ $this->printLogQuery(true, true, $this->getSelect());
115
+ throw $e;
116
+ }
117
+
118
+ $items = array();
119
+ foreach ($rows as $v) {
120
+ $items[trim($v[$idFieldName])] = $v;
121
+ }
122
+
123
+ foreach ($productIds as $productId => $additionalData) {
124
+ if (empty($items[$productId])) {
125
+ continue;
126
+ }
127
+
128
+ $v = array_merge($items[$productId], $additionalData->toArray());
129
+ $object = $this->getNewEmptyItem()
130
+ ->setData($v);
131
+
132
+ $this->addItem($object);
133
+ if (isset($this->_itemsById[$object->getId()])) {
134
+ $this->_itemsById[$object->getId()][] = $object;
135
+ } else {
136
+ $this->_itemsById[$object->getId()] = array($object);
137
+ }
138
+ }
139
+ }
140
+
141
+ return $this;
142
+ }
143
+
144
+
145
+ }
app/code/community/FACTFinder/Core/Model/Resource/Search/Engine.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Replaces the standard search engine
16
+ *
17
+ * The only thing we do here is setting our own search result collection
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_Resource_Search_Engine extends Mage_CatalogSearch_Model_Resource_Fulltext_Engine
27
+ {
28
+
29
+
30
+ /**
31
+ * Retrieve fulltext search result data collection
32
+ *
33
+ * @return FACTFinder_Core_Model_Resource_Search_Collection
34
+ */
35
+ public function getResultCollection()
36
+ {
37
+ return Mage::getResourceModel('factfinder/search_collection');
38
+ }
39
+
40
+
41
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Backend/Attributes.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Backend for serialized array data
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_System_Config_Backend_Attributes extends Mage_Core_Model_Config_Data
25
+ {
26
+
27
+
28
+ /**
29
+ * Process data after load
30
+ * @return void
31
+ */
32
+ protected function _afterLoad()
33
+ {
34
+ $value = $this->getValue();
35
+ $value = Mage::helper('factfinder/backend')->unserializeFieldValue($value);
36
+ $this->setValue($value);
37
+ }
38
+
39
+
40
+ /**
41
+ * Prepare data before save
42
+ *
43
+ * @return void
44
+ */
45
+ protected function _beforeSave()
46
+ {
47
+ $value = $this->getValue();
48
+ $value = Mage::helper('factfinder/backend')->serializeFieldValue($value);
49
+ $this->setValue($value);
50
+ }
51
+
52
+
53
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Log Cron Backend Model
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_System_Config_Backend_Cron extends Mage_Core_Model_Config_Data
25
+ {
26
+ const CRON_STRING_PATH = 'crontab/jobs/factfinder_generate/schedule/cron_expr';
27
+ const CRON_MODEL_PATH = 'crontab/jobs/factfinder_generate/run/model';
28
+
29
+
30
+ /**
31
+ * Cron settings after save
32
+ *
33
+ * @return Mage_Adminhtml_Model_System_Config_Backend_Log_Cron
34
+ */
35
+ protected function _afterSave()
36
+ {
37
+ $enabled = $this->getData('groups/cron/fields/enabled/value');
38
+ $time = $this->getData('groups/cron/fields/time/value');
39
+ $frequncy = $this->getData('groups/cron/fields/frequency/value');
40
+
41
+ $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
42
+ $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
43
+ $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
44
+
45
+ if ($enabled) {
46
+ $cronExprArray = array(
47
+ intval($time[1]), // Minute
48
+ intval($time[0]), // Hour
49
+ ($frequncy == $frequencyMonthly) ? '1' : '*', // Day of the Month
50
+ '*', // Month of the Year
51
+ ($frequncy == $frequencyWeekly) ? '1' : '*', // Day of the Week
52
+ );
53
+ $cronExprString = join(' ', $cronExprArray);
54
+ } else {
55
+ $cronExprString = '';
56
+ }
57
+
58
+ try {
59
+ Mage::getModel('core/config_data')
60
+ ->load(self::CRON_STRING_PATH, 'path')
61
+ ->setValue($cronExprString)
62
+ ->setPath(self::CRON_STRING_PATH)
63
+ ->save();
64
+
65
+ Mage::getModel('core/config_data')
66
+ ->load(self::CRON_MODEL_PATH, 'path')
67
+ ->setValue((string) Mage::getConfig()->getNode(self::CRON_MODEL_PATH))
68
+ ->setPath(self::CRON_MODEL_PATH)
69
+ ->save();
70
+ } catch (Exception $e) {
71
+ Mage::throwException(Mage::helper('adminhtml')->__('Unable to save the cron expression.'));
72
+ }
73
+ }
74
+
75
+
76
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Backend/Enabled.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * Status Enabled Config Field Backend
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_System_Config_Backend_Enabled extends Mage_Core_Model_Config_Data
27
+ {
28
+
29
+
30
+ /**
31
+ * Check request for errors found by Helper and Observer. It will print error messages if errors found and
32
+ * in that case set value to 0.
33
+ *
34
+ * @return FACTFinder_Core_Model_System_Config_Backend_Enabled
35
+ */
36
+ public function save()
37
+ {
38
+ parent::save();
39
+
40
+ Mage::app()->cleanCache();
41
+ $this->_checkConfiguration();
42
+
43
+ return $this;
44
+ }
45
+
46
+
47
+ /**
48
+ * Add message that ff cant be activated and specify reasons
49
+ *
50
+ * @param string $message
51
+ *
52
+ * @return void
53
+ */
54
+ protected function _addError($message = '')
55
+ {
56
+ $message = Mage::helper('factfinder')->__('FACT-Finder cannot be activated:') . '<br />' . $message;
57
+ Mage::getSingleton('adminhtml/session')->addError($message);
58
+ }
59
+
60
+
61
+ /**
62
+ * Check if the configuration if valid
63
+ *
64
+ * @return FACTFinder_Core_Model_System_Config_Backend_Enabled
65
+ */
66
+ protected function _checkConfiguration()
67
+ {
68
+
69
+ if (!$this->getValue()) {
70
+ return $this;
71
+ }
72
+
73
+ $groups = Mage::app()->getRequest()->getPost('groups');
74
+ $errors = Mage::helper('factfinder/backend')->checkConfigData($groups['search']['fields']);
75
+ if ($errors) {
76
+ $this->_addError(implode('<br />', $errors));
77
+ $this->setValue('0');
78
+ $this->save();
79
+ }
80
+
81
+ return $this;
82
+ }
83
+
84
+
85
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Source/Authtype.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * Provides Authtype Options
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Core
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Core_Model_System_Config_Source_Authtype
27
+ {
28
+
29
+
30
+ /**
31
+ * Get authtypes as option array
32
+ *
33
+ * @return array
34
+ */
35
+ public function toOptionArray()
36
+ {
37
+ return array(
38
+ array(
39
+ 'value' => 'http',
40
+ 'label' => Mage::helper('factfinder')->__('http')
41
+ ),
42
+ array(
43
+ 'value' => 'simple',
44
+ 'label' => Mage::helper('factfinder')->__('simple')
45
+ ),
46
+ array(
47
+ 'value' => 'advanced',
48
+ 'label' => Mage::helper('factfinder')->__('advanced')
49
+ )
50
+ );
51
+ }
52
+
53
+
54
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Source/Identifier.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_System_Config_Source_Identifier
25
+ {
26
+
27
+
28
+ /**
29
+ * Get possible identifiers as Option Array
30
+ *
31
+ * @return array
32
+ */
33
+ public function toOptionArray()
34
+ {
35
+ return array(
36
+ array(
37
+ 'value' => 'entity_id',
38
+ 'label' => Mage::helper('factfinder')->__('Product ID (default)')
39
+ ),
40
+ array(
41
+ 'value' => 'sku',
42
+ 'label' => Mage::helper('factfinder')->__('Product SKU')
43
+ )
44
+ );
45
+ }
46
+
47
+
48
+ }
app/code/community/FACTFinder/Core/Model/System/Config/Source/Protocol.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Core
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Core_Model_System_Config_Source_Protocol
25
+ {
26
+
27
+
28
+ /**
29
+ * Get possible protocols as Option Array
30
+ *
31
+ * @return array
32
+ */
33
+ public function toOptionArray()
34
+ {
35
+ return array(
36
+ array(
37
+ 'value' => 'http',
38
+ 'label' => Mage::helper('factfinder')->__('http')
39
+ ),
40
+ array(
41
+ 'value' => 'https',
42
+ 'label' => Mage::helper('factfinder')->__('https')
43
+ )
44
+ );
45
+ }
46
+
47
+
48
+ }
app/code/community/FACTFinder/Core/controllers/ExportController.php ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Controller class
16
+ *
17
+ * This class the Export Controller
18
+ * It provides a Products, Prices and Stocks Export
19
+ *
20
+ * @category Mage
21
+ * @package FACTFinder_Core
22
+ * @author Flagbit Magento Team <magento@flagbit.de>
23
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG (http://www.flagbit.de)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ * @link http://www.flagbit.de
26
+ */
27
+ class FACTFinder_Core_ExportController extends Mage_Core_Controller_Front_Action
28
+ {
29
+
30
+ const XML_AUTH_PASSWORD_PATH = 'factfinder/search/auth_password';
31
+
32
+
33
+ /**
34
+ * Handle Export Authentification
35
+ *
36
+ * @return Mage_Core_Controller_Varien_Action
37
+ */
38
+ public function preDispatch()
39
+ {
40
+ $this->_getStoreId();
41
+ $password = md5(Mage::getStoreConfig(self::XML_AUTH_PASSWORD_PATH));
42
+
43
+ if ($password == '' || $password != $this->getRequest()->getParam('key')) {
44
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
45
+ }
46
+
47
+ return parent::preDispatch();
48
+ }
49
+
50
+
51
+ /**
52
+ * Get current Store ID
53
+ *
54
+ * @return int
55
+ */
56
+ protected function _getStoreId()
57
+ {
58
+ if ($storeId = $this->getRequest()->getParam('store')) {
59
+ Mage::app()->setCurrentStore($storeId);
60
+ }
61
+
62
+ return Mage::app()->getStore()->getId();
63
+ }
64
+
65
+
66
+ /**
67
+ * Initialize Product Export
68
+ */
69
+ public function exportAction()
70
+ {
71
+ try {
72
+ $this->lockSemaphore();
73
+ } catch (RuntimeException $e) {
74
+ $this->loadLayout()
75
+ ->renderLayout();
76
+ return;
77
+ }
78
+
79
+ $resource = Mage::app()->getRequest()->getParam('resource', 'product');
80
+
81
+ try {
82
+ $exportModel = Mage::getModel('factfinder/export_' . $resource);
83
+ $exportModel->saveExport(
84
+ $this->_getStoreId()
85
+ );
86
+
87
+ $this->releaseSemaphore(); // finally-workaround
88
+ } catch (Exception $e) {
89
+ $this->releaseSemaphore(); // finally-workaround
90
+ throw $e;
91
+ }
92
+
93
+ $this->_forward('get');
94
+ }
95
+
96
+
97
+ /**
98
+ * Output pre-generated export files for a specific resource and store (for ff import process)
99
+ */
100
+ public function getAction()
101
+ {
102
+ $resource = Mage::app()->getRequest()->getParam('resource', 'product');
103
+
104
+ $fileName = 'store_' . $this->_getStoreId() . '_' . $resource . '.csv';
105
+ $filePath = Mage::getBaseDir() . DS . 'var' . DS . 'factfinder' . DS;
106
+
107
+ if (!file_exists($filePath . $fileName)) {
108
+ $this->loadLayout()
109
+ ->renderLayout();
110
+ return;
111
+ }
112
+
113
+ $this->getResponse()->setBody(
114
+ file_get_contents($filePath . $fileName)
115
+ );
116
+ }
117
+
118
+
119
+ /**
120
+ * Download pre-generated export files for a specific resource and store
121
+ */
122
+ public function downloadAction()
123
+ {
124
+ $resource = Mage::app()->getRequest()->getParam('resource', 'product');
125
+
126
+ $fileName = 'store_' . $this->_getStoreId() . '_' . $resource . '.csv';
127
+ $filePath = Mage::getBaseDir() . DS . 'var' . DS . 'factfinder' . DS;
128
+
129
+ if (!file_exists($filePath . $fileName)) {
130
+ $this->loadLayout()
131
+ ->renderLayout();
132
+ return;
133
+ }
134
+
135
+ $this->_prepareDownloadResponse(
136
+ $fileName,
137
+ array(
138
+ 'type' => 'filename',
139
+ 'value' => $filePath . $fileName
140
+ )
141
+ );
142
+ }
143
+
144
+
145
+ /**
146
+ * Add export action to cronjob table
147
+ */
148
+ public function scheduleExportAction()
149
+ {
150
+ $schedule = Mage::getModel('cron/schedule');
151
+ $schedule->setJobCode('factfinder_generate')
152
+ ->setCreatedAt(time())
153
+ ->setScheduledAt(time() + 60)
154
+ ->setStatus(Mage_Cron_Model_Schedule::STATUS_PENDING)
155
+ ->save();
156
+
157
+ $this->_redirectReferer();
158
+ }
159
+
160
+
161
+ /**
162
+ * Locks the semaphore
163
+ * Throws an exception, if semaphore is already locked
164
+ **/
165
+ protected function lockSemaphore()
166
+ {
167
+ $mtime = @filemtime($this->_getLockFileName());
168
+ $semaphoreTimeout = FACTFinderCustom_Configuration::DEFAULT_SEMAPHORE_TIMEOUT;
169
+ if ($mtime && time() - $mtime < $semaphoreTimeout) {
170
+ throw new RuntimeException();
171
+ }
172
+ @touch($this->_getLockFileName());
173
+ }
174
+
175
+
176
+ /**
177
+ * Release the semaphore
178
+ */
179
+ protected function releaseSemaphore()
180
+ {
181
+ @unlink($this->_getLockFileName());
182
+ }
183
+
184
+
185
+ /**
186
+ * Retrieve the name of lockfile
187
+ *
188
+ * @return string
189
+ */
190
+ protected function _getLockFileName()
191
+ {
192
+ return Mage::getBaseDir('var') . DS . 'locks' . DS . 'ffexport_' . $this->_getStoreId() . '.lock';
193
+ }
194
+
195
+
196
+ /**
197
+ * Used to forward actions from wrappers
198
+ *
199
+ * @param string $resource
200
+ *
201
+ * @return void
202
+ */
203
+ protected function _forwardExport($resource)
204
+ {
205
+ $params = $this->getRequest()->getParams();
206
+ $params = array_merge($params, array(
207
+ 'resource' => $resource,
208
+ ));
209
+
210
+ $this->_forward('export', null, null, $params);
211
+ }
212
+
213
+
214
+ /**
215
+ * Wrapper for price export
216
+ */
217
+ public function priceAction()
218
+ {
219
+ $this->_forwardExport('price');
220
+ }
221
+
222
+
223
+ /**
224
+ * Wrapper ro stock export
225
+ */
226
+ public function stockAction()
227
+ {
228
+ $this->_forwardExport('stock');
229
+ }
230
+
231
+
232
+ /**
233
+ * Wrapper for product export
234
+ */
235
+ public function productAction()
236
+ {
237
+ $this->_forwardExport('product');
238
+ }
239
+
240
+
241
+ }
app/code/community/FACTFinder/Core/etc/adminhtml.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Core
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Core
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <acl>
17
+ <resources>
18
+ <admin>
19
+ <children>
20
+ <system>
21
+ <children>
22
+ <config>
23
+ <children>
24
+ <factfinder>
25
+ <title>FACT-Finder</title>
26
+ </factfinder>
27
+ </children>
28
+ </config>
29
+ </children>
30
+ </system>
31
+ </children>
32
+ </admin>
33
+ </resources>
34
+ </acl>
35
+ </config>
app/code/community/FACTFinder/Core/etc/config.xml ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Core
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Core
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <modules>
17
+ <FACTFinder_Core>
18
+ <version>4.0.1</version>
19
+ </FACTFinder_Core>
20
+ </modules>
21
+ <global>
22
+ <models>
23
+ <factfinder>
24
+ <class>FACTFinder_Core_Model</class>
25
+ <resourceModel>factfinder_core_resource</resourceModel>
26
+ </factfinder>
27
+ <factfinder_core_resource>
28
+ <class>FACTFinder_Core_Model_Resource</class>
29
+ </factfinder_core_resource>
30
+ </models>
31
+ <blocks>
32
+ <factfinder>
33
+ <class>FACTFinder_Core_Block</class>
34
+ </factfinder>
35
+ </blocks>
36
+ <helpers>
37
+ <factfinder>
38
+ <class>FACTFinder_Core_Helper</class>
39
+ </factfinder>
40
+ </helpers>
41
+ <events>
42
+ <controller_front_init_before>
43
+ <observers>
44
+ <factfinder>
45
+ <class>factfinder/autoloader</class>
46
+ <method>addAutoloader</method>
47
+ </factfinder>
48
+ <factfinder_manage_modules>
49
+ <class>factfinder/observer</class>
50
+ <method>manageModules</method>
51
+ </factfinder_manage_modules>
52
+ </observers>
53
+ </controller_front_init_before>
54
+ <factfinder_export_after>
55
+ <observers>
56
+ <factfinder_core_import>
57
+ <class>factfinder/observer</class>
58
+ <method>triggerImportAfterExport</method>
59
+ </factfinder_core_import>
60
+ </observers>
61
+ </factfinder_export_after>
62
+ </events>
63
+ </global>
64
+ <adminhtml>
65
+ <events>
66
+ <controller_action_postdispatch_adminhtml_system_config_save>
67
+ <observers>
68
+ <factfinder_core_set_search_engine>
69
+ <class>factfinder/observer</class>
70
+ <method>setSearchEngine</method>
71
+ </factfinder_core_set_search_engine>
72
+ </observers>
73
+ </controller_action_postdispatch_adminhtml_system_config_save>
74
+ </events>
75
+ </adminhtml>
76
+ <frontend>
77
+ <events>
78
+ <controller_action_predispatch_catalogsearch_result_index>
79
+ <observers>
80
+ <factfinder_core_reset_search_layer>
81
+ <class>factfinder/observer</class>
82
+ <method>resetCurrentSearchLayer</method>
83
+ </factfinder_core_reset_search_layer>
84
+ </observers>
85
+ </controller_action_predispatch_catalogsearch_result_index>
86
+ <controller_action_predispatch_catalogsearch_advanced_result>
87
+ <observers>
88
+ <factfinder_core_reset_search_layer>
89
+ <class>factfinder/observer</class>
90
+ <method>resetCurrentSearchLayer</method>
91
+ </factfinder_core_reset_search_layer>
92
+ </observers>
93
+ </controller_action_predispatch_catalogsearch_advanced_result>
94
+ <core_block_abstract_prepare_layout_after>
95
+ <observers>
96
+ <factfinder_core_remove_layer_filters>
97
+ <class>factfinder/observer</class>
98
+ <method>removeLayerFilters</method>
99
+ </factfinder_core_remove_layer_filters>
100
+ </observers>
101
+ </core_block_abstract_prepare_layout_after>
102
+ <controller_action_layout_generate_blocks_after>
103
+ <observers>
104
+ <factfinder_handle_single_product_redirect>
105
+ <class>factfinder/observer</class>
106
+ <method>handleSingleProductRedirect</method>
107
+ </factfinder_handle_single_product_redirect>
108
+ </observers>
109
+ </controller_action_layout_generate_blocks_after>
110
+ </events>
111
+ <routers>
112
+ <factfinder>
113
+ <use>standard</use>
114
+ <args>
115
+ <module>FACTFinder_Core</module>
116
+ <frontName>factfinder</frontName>
117
+ </args>
118
+ </factfinder>
119
+ </routers>
120
+ <layout>
121
+ <updates>
122
+ <factfinder_core>
123
+ <file>factfinder/core.xml</file>
124
+ </factfinder_core>
125
+ </updates>
126
+ </layout>
127
+ </frontend>
128
+ <default>
129
+ <factfinder>
130
+ <config>
131
+ <debug>1</debug>
132
+ <identifier>entity_id</identifier>
133
+ </config>
134
+ <search>
135
+ <address>cname.fact-finder.com</address>
136
+ <port>80</port>
137
+ <protocol>http</protocol>
138
+ <context>FACT-Finder</context>
139
+ <!-- possible values: http, https -->
140
+ <auth_type>advanced</auth_type>
141
+ <!-- possible values: http (for FF <= 6.4); simple | advanced (for FF >= 6.5)-->
142
+ <auth_advancedPrefix>FACT-FINDER</auth_advancedPrefix>
143
+ <auth_advancedPostfix>FACT-FINDER</auth_advancedPostfix>
144
+
145
+ <!-- encoding settings -->
146
+ <encoding>
147
+ <pageContent>UTF-8</pageContent>
148
+ <serverURI>UTF-8</serverURI>
149
+ <pageURI>UTF-8</pageURI>
150
+ </encoding>
151
+ </search>
152
+ <fallback>
153
+ <use_fallback>0</use_fallback>
154
+ </fallback>
155
+ <export>
156
+ <remove_tags>1</remove_tags>
157
+ </export>
158
+ <modules>
159
+ <asn>1</asn>
160
+ <suggest>1</suggest>
161
+ <tracking>1</tracking>
162
+ </modules>
163
+ </factfinder>
164
+ <advanced>
165
+ <ff_modules>
166
+ <asn>1</asn>
167
+ <suggest>1</suggest>
168
+ <campaigns>1</campaigns>
169
+ <tracking>1</tracking>
170
+ <recommendation>1</recommendation>
171
+ <tagcloud>1</tagcloud>
172
+ </ff_modules>
173
+ </advanced>
174
+ </default>
175
+ <crontab>
176
+ <jobs>
177
+ <factfinder_generate>
178
+ <run>
179
+ <model>factfinder/export_product::saveAll</model>
180
+ </run>
181
+ </factfinder_generate>
182
+ </jobs>
183
+ </crontab>
184
+ </config>
app/code/community/{Flagbit/FactFinder → FACTFinder/Core}/etc/system.xml RENAMED
@@ -1,398 +1,442 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * System Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
- <config>
22
- <sections>
23
- <factfinder translate="label" module="factfinder">
24
- <label>FACT-Finder</label>
25
- <tab>catalog</tab>
26
- <sort_order>420</sort_order>
27
- <frontend_type>text</frontend_type>
28
- <show_in_default>1</show_in_default>
29
- <show_in_website>1</show_in_website>
30
- <show_in_store>1</show_in_store>
31
- <groups>
32
- <search translate="label">
33
- <label>FACT-Finder Access Data</label>
34
- <frontend_type>text</frontend_type>
35
- <sort_order>10</sort_order>
36
- <show_in_default>1</show_in_default>
37
- <show_in_website>1</show_in_website>
38
- <show_in_store>1</show_in_store>
39
- <fields>
40
- <enabled translate="label">
41
- <label>Enabled</label>
42
- <frontend_type>select</frontend_type>
43
- <source_model>adminhtml/system_config_source_yesno</source_model>
44
- <backend_model>factfinder/system_config_backend_enabled</backend_model>
45
- <show_in_default>1</show_in_default>
46
- <show_in_website>1</show_in_website>
47
- <show_in_store>1</show_in_store>
48
- </enabled>
49
- <address translate="label">
50
- <label>Server URL</label>
51
- <frontend_type>text</frontend_type>
52
- <sort_order>20</sort_order>
53
- <show_in_default>1</show_in_default>
54
- <show_in_website>1</show_in_website>
55
- <show_in_store>1</show_in_store>
56
- </address>
57
- <port translate="label">
58
- <label>Server Port</label>
59
- <frontend_type>text</frontend_type>
60
- <sort_order>30</sort_order>
61
- <show_in_default>1</show_in_default>
62
- <show_in_website>1</show_in_website>
63
- <show_in_store>1</show_in_store>
64
- </port>
65
- <context translate="label comment">
66
- <label>Context Name</label>
67
- <comment>Name of the FACT-Finder application</comment>
68
- <frontend_type>text</frontend_type>
69
- <sort_order>40</sort_order>
70
- <show_in_default>1</show_in_default>
71
- <show_in_website>1</show_in_website>
72
- <show_in_store>1</show_in_store>
73
- </context>
74
- <ffversion translate="label comment">
75
- <label>FACT-Finder version</label>
76
- <comment>Please select the version of your FACT-Finder application to enable all of its features.</comment>
77
- <frontend_type>select</frontend_type>
78
- <source_model>factfinder/system_config_source_ffversion</source_model>
79
- <sort_order>45</sort_order>
80
- <show_in_default>1</show_in_default>
81
- <show_in_website>1</show_in_website>
82
- <show_in_store>1</show_in_store>
83
- </ffversion>
84
- <auth_user translate="label comment">
85
- <label>User name</label>
86
- <comment>User name for authentication</comment>
87
- <frontend_type>text</frontend_type>
88
- <sort_order>50</sort_order>
89
- <show_in_default>1</show_in_default>
90
- <show_in_website>1</show_in_website>
91
- <show_in_store>1</show_in_store>
92
- </auth_user>
93
- <auth_password translate="label">
94
- <label>Password</label>
95
- <frontend_type>password</frontend_type>
96
- <sort_order>60</sort_order>
97
- <show_in_default>1</show_in_default>
98
- <show_in_website>1</show_in_website>
99
- <show_in_store>1</show_in_store>
100
- </auth_password>
101
- <channel translate="label comment">
102
- <label>Primary Channel</label>
103
- <comment>FACT-Finder can provide multiple search indexes, each represented by a "channel". Enter the channel that will be filled with your Magento export. Leave empty to use the default channel.</comment>
104
- <frontend_type>text</frontend_type>
105
- <sort_order>70</sort_order>
106
- <show_in_default>1</show_in_default>
107
- <show_in_website>1</show_in_website>
108
- <show_in_store>1</show_in_store>
109
- </channel>
110
- <secondary_channels translate="label">
111
- <label>Secondary Channels</label>
112
- <comment>Enter any secondary channels you want to search. Multiple channels should be separated by semicolons. NOTE: Secondary channels will only be considered for Suggest results if the proxy is used (see option in section "FACT-Finder Config Data")!</comment>
113
- <frontend_type>text</frontend_type>
114
- <sort_order>75</sort_order>
115
- <show_in_default>1</show_in_default>
116
- <show_in_website>1</show_in_website>
117
- <show_in_store>1</show_in_store>
118
- </secondary_channels>
119
- <language translate="label comment">
120
- <label>Language</label>
121
- <comment>Some text strings come directly from FACT-Finder. Enter the language code here. Leave empty to use the language specified by the user's browser.</comment>
122
- <frontend_type>text</frontend_type>
123
- <sort_order>80</sort_order>
124
- <show_in_default>1</show_in_default>
125
- <show_in_website>1</show_in_website>
126
- <show_in_store>1</show_in_store>
127
- </language>
128
- <auth_type translate="label">
129
- <label>Authentication Type</label>
130
- <frontend_type>select</frontend_type>
131
- <source_model>factfinder/system_config_source_authtype</source_model>
132
- <sort_order>90</sort_order>
133
- <show_in_default>1</show_in_default>
134
- <show_in_website>1</show_in_website>
135
- <show_in_store>1</show_in_store>
136
- </auth_type>
137
- <auth_advancedPrefix translate="label comment">
138
- <label>Advanced Authentication Prefix</label>
139
- <frontend_type>text</frontend_type>
140
- <comment>The advanced authentication post- and prefix are only used when the authentication type is "advanced".</comment>
141
- <sort_order>100</sort_order>
142
- <show_in_default>1</show_in_default>
143
- <show_in_website>1</show_in_website>
144
- <show_in_store>1</show_in_store>
145
- </auth_advancedPrefix>
146
- <auth_advancedPostfix>
147
- <label>Advanced Authentication Postfix</label>
148
- <frontend_type>text</frontend_type>
149
- <sort_order>110</sort_order>
150
- <show_in_default>1</show_in_default>
151
- <show_in_website>1</show_in_website>
152
- <show_in_store>1</show_in_store>
153
- </auth_advancedPostfix>
154
- </fields>
155
- </search>
156
- <fallback translate="label">
157
- <label>FACT-Finder Fallback Configuration</label>
158
- <frontend_type>text</frontend_type>
159
- <sort_order>15</sort_order>
160
- <show_in_default>1</show_in_default>
161
- <show_in_website>1</show_in_website>
162
- <show_in_store>1</show_in_store>
163
- <fields>
164
- <use_fallback translate="label comment">
165
- <label>Use Fallback</label>
166
- <comment>If activated and FACT-Finder cannot be contacted, Magento's built-in search will be used instead.</comment>
167
- <frontend_type>select</frontend_type>
168
- <source_model>adminhtml/system_config_source_yesno</source_model>
169
- <sort_order>10</sort_order>
170
- <show_in_default>1</show_in_default>
171
- <show_in_website>1</show_in_website>
172
- <show_in_store>1</show_in_store>
173
- </use_fallback>
174
- <wait_time translate="label comment">
175
- <label>Minutes before next attempt</label>
176
- <comment>After three failed attempts, the module can revert to using Magento for searches. After the specified amount of time has passed, the module will try to contact FACT-Finder again. If you enter 0, the module will first attempt to contact FACT-Finder for every search.</comment>
177
- <frontend_type>text</frontend_type>
178
- <sort_order>20</sort_order>
179
- <show_in_default>1</show_in_default>
180
- <show_in_website>1</show_in_website>
181
- <show_in_store>1</show_in_store>
182
- </wait_time>
183
- </fields>
184
- </fallback>
185
- <export translate="label">
186
- <label>FACT-Finder Export Configuration</label>
187
- <frontend_type>text</frontend_type>
188
- <sort_order>20</sort_order>
189
- <show_in_default>1</show_in_default>
190
- <show_in_website>1</show_in_website>
191
- <show_in_store>1</show_in_store>
192
- <fields>
193
- <urls translate="label">
194
- <label>Export Images and Deeplinks</label>
195
- <frontend_type>select</frontend_type>
196
- <source_model>adminhtml/system_config_source_yesno</source_model>
197
- <sort_order>10</sort_order>
198
- <show_in_default>1</show_in_default>
199
- <show_in_website>1</show_in_website>
200
- <show_in_store>1</show_in_store>
201
- </urls>
202
- <suggest_image_size translate="label comment">
203
- <label>Size of Suggest images</label>
204
- <comment>Please enter the desired edge length of the Suggest images in pixels. If you do not want them to be resized, enter 0.</comment>
205
- <frontend_type>text</frontend_type>
206
- <sort_order>15</sort_order>
207
- <show_in_default>1</show_in_default>
208
- <show_in_website>1</show_in_website>
209
- <show_in_store>1</show_in_store>
210
- </suggest_image_size>
211
- <suggest_image_type translate="label">
212
- <label>Type of Suggest images</label>
213
- <frontend_type>select</frontend_type>
214
- <source_model>factfinder/system_config_source_imagetype</source_model>
215
- <sort_order>16</sort_order>
216
- <show_in_default>1</show_in_default>
217
- <show_in_website>1</show_in_website>
218
- <show_in_store>1</show_in_store>
219
- </suggest_image_type>
220
- <clicktracking translate="label">
221
- <label>Track product-clicks</label>
222
- <frontend_type>select</frontend_type>
223
- <source_model>adminhtml/system_config_source_yesno</source_model>
224
- <sort_order>20</sort_order>
225
- <show_in_default>1</show_in_default>
226
- <show_in_website>1</show_in_website>
227
- <show_in_store>1</show_in_store>
228
- </clicktracking>
229
- <track_carts translate="label">
230
- <label>Track "Add to cart" events</label>
231
- <frontend_type>select</frontend_type>
232
- <source_model>adminhtml/system_config_source_yesno</source_model>
233
- <sort_order>30</sort_order>
234
- <show_in_default>1</show_in_default>
235
- <show_in_website>1</show_in_website>
236
- <show_in_store>1</show_in_store>
237
- </track_carts>
238
- <track_checkout translate="label">
239
- <label>Track checkout</label>
240
- <frontend_type>select</frontend_type>
241
- <source_model>adminhtml/system_config_source_yesno</source_model>
242
- <sort_order>40</sort_order>
243
- <show_in_default>1</show_in_default>
244
- <show_in_website>1</show_in_website>
245
- <show_in_store>1</show_in_store>
246
- </track_checkout>
247
- <attributes translate="label">
248
- <label>Attributes</label>
249
- <frontend_model>factfinder/adminhtml_form_field_attributes</frontend_model>
250
- <backend_model>factfinder/system_config_backend_attributes</backend_model>
251
- <sort_order>50</sort_order>
252
- <show_in_default>0</show_in_default>
253
- <show_in_website>0</show_in_website>
254
- <show_in_store>1</show_in_store>
255
- </attributes>
256
- <export_url translate="label">
257
- <label></label>
258
- <frontend_model>factfinder/adminhtml_exportlink</frontend_model>
259
- <sort_order>60</sort_order>
260
- <show_in_default>1</show_in_default>
261
- <show_in_website>1</show_in_website>
262
- <show_in_store>1</show_in_store>
263
- </export_url>
264
- </fields>
265
- </export>
266
- <config translate="label">
267
- <label>FACT-Finder Config Data</label>
268
- <frontend_type>text</frontend_type>
269
- <sort_order>30</sort_order>
270
- <show_in_default>1</show_in_default>
271
- <show_in_website>1</show_in_website>
272
- <show_in_store>1</show_in_store>
273
- <fields>
274
- <identifier translate="label">
275
- <label>Product Identifier</label>
276
- <frontend_type>select</frontend_type>
277
- <source_model>factfinder/system_config_source_identifier</source_model>
278
- <sort_order>10</sort_order>
279
- <show_in_default>1</show_in_default>
280
- <show_in_website>1</show_in_website>
281
- <show_in_store>1</show_in_store>
282
- </identifier>
283
- <redirectOnSingleResult>
284
- <label>Redirect to product details page for single results</label>
285
- <frontend_type>select</frontend_type>
286
- <source_model>adminhtml/system_config_source_yesno</source_model>
287
- <sort_order>20</sort_order>
288
- <show_in_default>1</show_in_default>
289
- <show_in_website>1</show_in_website>
290
- <show_in_store>1</show_in_store>
291
- </redirectOnSingleResult>
292
- <proxy translate="label">
293
- <label>Use Proxy for Suggest</label>
294
- <comment>This option must be enabled if secondary channels are to be considered for Suggest results.</comment>
295
- <frontend_type>select</frontend_type>
296
- <source_model>adminhtml/system_config_source_yesno</source_model>
297
- <sort_order>30</sort_order>
298
- <show_in_default>1</show_in_default>
299
- <show_in_website>1</show_in_website>
300
- <show_in_store>1</show_in_store>
301
- </proxy>
302
- <internal_ip translate="label">
303
- <label>Internal IPs</label>
304
- <comment>Enter your internal IP addresses. Multiple IP addresses should be separated by semicolons.</comment>
305
- <frontend_type>text</frontend_type>
306
- <sort_order>40</sort_order>
307
- <show_in_default>1</show_in_default>
308
- <show_in_website>1</show_in_website>
309
- <show_in_store>1</show_in_store>
310
- </internal_ip>
311
- <debug translate="label">
312
- <label>Debug Log</label>
313
- <frontend_type>select</frontend_type>
314
- <source_model>adminhtml/system_config_source_yesno</source_model>
315
- <sort_order>50</sort_order>
316
- <show_in_default>1</show_in_default>
317
- <show_in_website>1</show_in_website>
318
- <show_in_store>1</show_in_store>
319
- </debug>
320
- </fields>
321
- </config>
322
- <activation translate="label">
323
- <label>FACT-Finder Module Activation</label>
324
- <frontend_type>text</frontend_type>
325
- <sort_order>40</sort_order>
326
- <show_in_default>1</show_in_default>
327
- <show_in_website>1</show_in_website>
328
- <show_in_store>1</show_in_store>
329
- <fields>
330
- <suggest translate="label">
331
- <label>Use FACT-Finder Suggest Functionality</label>
332
- <frontend_type>select</frontend_type>
333
- <source_model>adminhtml/system_config_source_yesno</source_model>
334
- <sort_order>10</sort_order>
335
- <show_in_default>1</show_in_default>
336
- <show_in_website>1</show_in_website>
337
- <show_in_store>1</show_in_store>
338
- </suggest>
339
- <campaign translate="label">
340
- <label>Use FACT-Finder Campaign Functionality</label>
341
- <frontend_type>select</frontend_type>
342
- <source_model>adminhtml/system_config_source_yesno</source_model>
343
- <sort_order>20</sort_order>
344
- <show_in_default>1</show_in_default>
345
- <show_in_website>1</show_in_website>
346
- <show_in_store>1</show_in_store>
347
- </campaign>
348
- <asn translate="label">
349
- <label>Use FACT-Finder After Search Navigation Functionality</label>
350
- <frontend_type>select</frontend_type>
351
- <source_model>adminhtml/system_config_source_yesno</source_model>
352
- <sort_order>30</sort_order>
353
- <show_in_default>1</show_in_default>
354
- <show_in_website>1</show_in_website>
355
- <show_in_store>1</show_in_store>
356
- </asn>
357
- <navigation translate="label">
358
- <label>Use FACT-Finder for Layered Navigation</label>
359
- <frontend_type>select</frontend_type>
360
- <source_model>adminhtml/system_config_source_yesno</source_model>
361
- <sort_order>50</sort_order>
362
- <show_in_default>1</show_in_default>
363
- <show_in_website>1</show_in_website>
364
- <show_in_store>1</show_in_store>
365
- </navigation>
366
- <upsell translate="label">
367
- <label>Use FACT-Finder for product upselling</label>
368
- <frontend_type>select</frontend_type>
369
- <source_model>adminhtml/system_config_source_yesno</source_model>
370
- <sort_order>60</sort_order>
371
- <show_in_default>1</show_in_default>
372
- <show_in_website>1</show_in_website>
373
- <show_in_store>1</show_in_store>
374
- </upsell>
375
- <crosssell translate="label">
376
- <label>Use FACT-Finder for product cross-selling</label>
377
- <frontend_type>select</frontend_type>
378
- <source_model>adminhtml/system_config_source_yesno</source_model>
379
- <sort_order>70</sort_order>
380
- <show_in_default>1</show_in_default>
381
- <show_in_website>1</show_in_website>
382
- <show_in_store>1</show_in_store>
383
- </crosssell>
384
- <tagcloud translate="label">
385
- <label>Use FACT-Finder for tag cloud computation</label>
386
- <frontend_type>select</frontend_type>
387
- <source_model>adminhtml/system_config_source_yesno</source_model>
388
- <sort_order>80</sort_order>
389
- <show_in_default>1</show_in_default>
390
- <show_in_website>1</show_in_website>
391
- <show_in_store>1</show_in_store>
392
- </tagcloud>
393
- </fields>
394
- </activation>
395
- </groups>
396
- </factfinder>
397
- </sections>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  </config>
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Core
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Core
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <sections>
17
+ <factfinder translate="label" module="factfinder">
18
+ <label>FACT-Finder</label>
19
+ <tab>catalog</tab>
20
+ <sort_order>420</sort_order>
21
+ <frontend_type>text</frontend_type>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <show_in_store>1</show_in_store>
25
+ <groups>
26
+ <search translate="label">
27
+ <label>FACT-Finder</label>
28
+ <frontend_type>text</frontend_type>
29
+ <sort_order>10</sort_order>
30
+ <show_in_default>1</show_in_default>
31
+ <show_in_website>1</show_in_website>
32
+ <show_in_store>1</show_in_store>
33
+ <fields>
34
+ <enabled translate="label">
35
+ <label>Enabled</label>
36
+ <frontend_type>select</frontend_type>
37
+ <source_model>adminhtml/system_config_source_yesno</source_model>
38
+ <sort_order>10</sort_order>
39
+ <!--<backend_model>factfinder/system_config_backend_enabled</backend_model>-->
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ </enabled>
44
+ <address translate="label">
45
+ <label>Server URL</label>
46
+ <frontend_type>text</frontend_type>
47
+ <sort_order>20</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
+ </address>
52
+ <port translate="label">
53
+ <label>Server Port</label>
54
+ <frontend_type>text</frontend_type>
55
+ <sort_order>30</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>1</show_in_website>
58
+ <show_in_store>1</show_in_store>
59
+ </port>
60
+ <protocol translate="label">
61
+ <label>Protocol</label>
62
+ <frontend_type>select</frontend_type>
63
+ <source_model>factfinder/system_config_source_protocol</source_model>
64
+ <sort_order>35</sort_order>
65
+ <show_in_default>1</show_in_default>
66
+ <show_in_website>1</show_in_website>
67
+ <show_in_store>1</show_in_store>
68
+ </protocol>
69
+ <context translate="label comment">
70
+ <label>Context Name</label>
71
+ <comment>Name of the FACT-Finder application</comment>
72
+ <frontend_type>text</frontend_type>
73
+ <sort_order>40</sort_order>
74
+ <show_in_default>1</show_in_default>
75
+ <show_in_website>1</show_in_website>
76
+ <show_in_store>1</show_in_store>
77
+ </context>
78
+ <auth_user translate="label comment">
79
+ <label>User name</label>
80
+ <comment>User name for authentication</comment>
81
+ <frontend_type>text</frontend_type>
82
+ <sort_order>50</sort_order>
83
+ <show_in_default>1</show_in_default>
84
+ <show_in_website>1</show_in_website>
85
+ <show_in_store>1</show_in_store>
86
+ </auth_user>
87
+ <auth_password translate="label">
88
+ <label>Password</label>
89
+ <frontend_type>password</frontend_type>
90
+ <sort_order>60</sort_order>
91
+ <show_in_default>1</show_in_default>
92
+ <show_in_website>1</show_in_website>
93
+ <show_in_store>1</show_in_store>
94
+ </auth_password>
95
+ <channel translate="label comment">
96
+ <label>Primary Channel</label>
97
+ <comment>FACT-Finder can provide multiple search indexes, each represented by a "channel". Enter the channel that will be filled with your Magento export. Leave empty to use the default channel.</comment>
98
+ <frontend_type>text</frontend_type>
99
+ <sort_order>70</sort_order>
100
+ <show_in_default>1</show_in_default>
101
+ <show_in_website>1</show_in_website>
102
+ <show_in_store>1</show_in_store>
103
+ </channel>
104
+ <language translate="label comment">
105
+ <label>Language</label>
106
+ <comment>Some text strings come directly from FACT-Finder. Enter the language code here. Leave empty to use the language specified by the user's browser.</comment>
107
+ <frontend_type>text</frontend_type>
108
+ <sort_order>80</sort_order>
109
+ <show_in_default>1</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>1</show_in_store>
112
+ </language>
113
+ <auth_type translate="label">
114
+ <label>Authentication Type</label>
115
+ <frontend_type>select</frontend_type>
116
+ <source_model>factfinder/system_config_source_authtype</source_model>
117
+ <sort_order>90</sort_order>
118
+ <show_in_default>1</show_in_default>
119
+ <show_in_website>1</show_in_website>
120
+ <show_in_store>1</show_in_store>
121
+ </auth_type>
122
+ <auth_advancedPrefix translate="label comment">
123
+ <label>Advanced Authentication Prefix</label>
124
+ <frontend_type>text</frontend_type>
125
+ <comment>The advanced authentication post- and prefix are only used when the authentication type is "advanced".</comment>
126
+ <sort_order>100</sort_order>
127
+ <show_in_default>1</show_in_default>
128
+ <show_in_website>1</show_in_website>
129
+ <show_in_store>1</show_in_store>
130
+ </auth_advancedPrefix>
131
+ <auth_advancedPostfix>
132
+ <label>Advanced Authentication Postfix</label>
133
+ <frontend_type>text</frontend_type>
134
+ <sort_order>110</sort_order>
135
+ <show_in_default>1</show_in_default>
136
+ <show_in_website>1</show_in_website>
137
+ <show_in_store>1</show_in_store>
138
+ </auth_advancedPostfix>
139
+ </fields>
140
+ </search>
141
+ <fallback translate="label">
142
+ <label>FACT-Finder Fallback Configuration</label>
143
+ <frontend_type>text</frontend_type>
144
+ <sort_order>15</sort_order>
145
+ <show_in_default>1</show_in_default>
146
+ <show_in_website>1</show_in_website>
147
+ <show_in_store>1</show_in_store>
148
+ <fields>
149
+ <use_fallback translate="label comment">
150
+ <label>Use Fallback</label>
151
+ <comment>If activated and FACT-Finder cannot be contacted, Magento's built-in search will be used instead.</comment>
152
+ <frontend_type>select</frontend_type>
153
+ <source_model>adminhtml/system_config_source_yesno</source_model>
154
+ <sort_order>10</sort_order>
155
+ <show_in_default>1</show_in_default>
156
+ <show_in_website>1</show_in_website>
157
+ <show_in_store>1</show_in_store>
158
+ </use_fallback>
159
+ </fields>
160
+ </fallback>
161
+ <export translate="label">
162
+ <label>FACT-Finder Export Configuration</label>
163
+ <frontend_type>text</frontend_type>
164
+ <sort_order>20</sort_order>
165
+ <show_in_default>1</show_in_default>
166
+ <show_in_website>1</show_in_website>
167
+ <show_in_store>1</show_in_store>
168
+ <fields>
169
+ <products_without_categories translate="label">
170
+ <label>Export products without categories</label>
171
+ <frontend_type>select</frontend_type>
172
+ <source_model>adminhtml/system_config_source_yesno</source_model>
173
+ <sort_order>11</sort_order>
174
+ <show_in_default>1</show_in_default>
175
+ <show_in_website>1</show_in_website>
176
+ <show_in_store>1</show_in_store>
177
+ </products_without_categories>
178
+ <remove_tags translate="label">
179
+ <label>Remove html entities and tags</label>
180
+ <frontend_type>select</frontend_type>
181
+ <source_model>adminhtml/system_config_source_yesno</source_model>
182
+ <sort_order>55</sort_order>
183
+ <show_in_default>1</show_in_default>
184
+ <show_in_website>1</show_in_website>
185
+ <show_in_store>1</show_in_store>
186
+ </remove_tags>
187
+ <attributes translate="label">
188
+ <label>Attributes</label>
189
+ <frontend_model>factfinder/adminhtml_form_field_attributes</frontend_model>
190
+ <backend_model>factfinder/system_config_backend_attributes</backend_model>
191
+ <sort_order>50</sort_order>
192
+ <show_in_default>1</show_in_default>
193
+ <show_in_website>1</show_in_website>
194
+ <show_in_store>1</show_in_store>
195
+ </attributes>
196
+ <export_url translate="label">
197
+ <frontend_model>factfinder/adminhtml_exportlink</frontend_model>
198
+ <sort_order>60</sort_order>
199
+ <show_in_default>1</show_in_default>
200
+ <show_in_website>1</show_in_website>
201
+ <show_in_store>1</show_in_store>
202
+ </export_url>
203
+ <trigger_data_import translate="label">
204
+ <label>Trigger Data Import</label>
205
+ <frontend_type>select</frontend_type>
206
+ <source_model>adminhtml/system_config_source_yesno</source_model>
207
+ <sort_order>70</sort_order>
208
+ <show_in_default>1</show_in_default>
209
+ <show_in_website>1</show_in_website>
210
+ <show_in_store>1</show_in_store>
211
+ <comment><![CDATA[Start FACTFinder data import after each export]]></comment>
212
+ </trigger_data_import>
213
+ </fields>
214
+ </export>
215
+ <config translate="label">
216
+ <label>FACT-Finder Config Data</label>
217
+ <frontend_type>text</frontend_type>
218
+ <sort_order>20</sort_order>
219
+ <show_in_default>1</show_in_default>
220
+ <show_in_website>1</show_in_website>
221
+ <show_in_store>1</show_in_store>
222
+ <fields>
223
+ <personalization translate="label">
224
+ <label>Enable Personalization (>= 7.0)</label>
225
+ <frontend_type>select</frontend_type>
226
+ <source_model>adminhtml/system_config_source_yesno</source_model>
227
+ <sort_order>5</sort_order>
228
+ <show_in_default>1</show_in_default>
229
+ <show_in_website>1</show_in_website>
230
+ <show_in_store>1</show_in_store>
231
+ </personalization>
232
+ <identifier translate="label">
233
+ <label>Product Identifier</label>
234
+ <frontend_type>select</frontend_type>
235
+ <source_model>factfinder/system_config_source_identifier</source_model>
236
+ <sort_order>10</sort_order>
237
+ <show_in_default>1</show_in_default>
238
+ <show_in_website>1</show_in_website>
239
+ <show_in_store>1</show_in_store>
240
+ </identifier>
241
+ <redirectOnSingleResult>
242
+ <label>Redirect to product details page for single results</label>
243
+ <frontend_type>select</frontend_type>
244
+ <source_model>adminhtml/system_config_source_yesno</source_model>
245
+ <sort_order>20</sort_order>
246
+ <show_in_default>1</show_in_default>
247
+ <show_in_website>1</show_in_website>
248
+ <show_in_store>1</show_in_store>
249
+ </redirectOnSingleResult>
250
+ <internal_ip translate="label">
251
+ <label>Internal IPs</label>
252
+ <comment>Enter your internal IP addresses. Multiple IP addresses should be separated by semicolons.</comment>
253
+ <frontend_type>text</frontend_type>
254
+ <sort_order>40</sort_order>
255
+ <show_in_default>1</show_in_default>
256
+ <show_in_website>1</show_in_website>
257
+ <show_in_store>1</show_in_store>
258
+ </internal_ip>
259
+ <debug translate="label">
260
+ <label>Debug Log</label>
261
+ <frontend_type>select</frontend_type>
262
+ <source_model>adminhtml/system_config_source_yesno</source_model>
263
+ <sort_order>50</sort_order>
264
+ <show_in_default>1</show_in_default>
265
+ <show_in_website>1</show_in_website>
266
+ <show_in_store>1</show_in_store>
267
+ </debug>
268
+ </fields>
269
+ </config>
270
+ <cron translate="label">
271
+ <label>FACT-Finder Cron Export Settings</label>
272
+ <frontend_type>text</frontend_type>
273
+ <sort_order>25</sort_order>
274
+ <show_in_default>1</show_in_default>
275
+ <show_in_website>0</show_in_website>
276
+ <show_in_store>0</show_in_store>
277
+ <fields>
278
+ <enabled translate="label">
279
+ <label>Enable Cron Pre-Generation</label>
280
+ <frontend_type>select</frontend_type>
281
+ <source_model>adminhtml/system_config_source_yesno</source_model>
282
+ <sort_order>10</sort_order>
283
+ <show_in_default>1</show_in_default>
284
+ <show_in_website>0</show_in_website>
285
+ <show_in_store>0</show_in_store>
286
+ </enabled>
287
+ <time translate="label">
288
+ <label>Start Time</label>
289
+ <frontend_type>time</frontend_type>
290
+ <sort_order>20</sort_order>
291
+ <show_in_default>1</show_in_default>
292
+ <show_in_website>0</show_in_website>
293
+ <show_in_store>0</show_in_store>
294
+ </time>
295
+ <frequency translate="label">
296
+ <label>Frequency</label>
297
+ <frontend_type>select</frontend_type>
298
+ <source_model>adminhtml/system_config_source_cron_frequency</source_model>
299
+ <backend_model>factfinder/system_config_backend_cron</backend_model>
300
+ <sort_order>30</sort_order>
301
+ <show_in_default>1</show_in_default>
302
+ <show_in_website>0</show_in_website>
303
+ <show_in_store>0</show_in_store>
304
+ </frequency>
305
+ </fields>
306
+ </cron>
307
+ <modules translate="label">
308
+ <label>FACT-Finder Features</label>
309
+ <sort_order>50</sort_order>
310
+ <show_in_default>1</show_in_default>
311
+ <show_in_website>1</show_in_website>
312
+ <show_in_store>1</show_in_store>
313
+ <fields>
314
+ <asn translate="label">
315
+ <label>Enable FACT-Finder After Search Navigation</label>
316
+ <frontend_type>select</frontend_type>
317
+ <source_model>adminhtml/system_config_source_yesno</source_model>
318
+ <sort_order>10</sort_order>
319
+ <show_in_default>1</show_in_default>
320
+ <show_in_website>1</show_in_website>
321
+ <show_in_store>1</show_in_store>
322
+ </asn>
323
+ <suggest translate="label">
324
+ <label>Enable FACT-Finder Suggest</label>
325
+ <frontend_type>select</frontend_type>
326
+ <source_model>adminhtml/system_config_source_yesno</source_model>
327
+ <sort_order>20</sort_order>
328
+ <show_in_default>1</show_in_default>
329
+ <show_in_website>1</show_in_website>
330
+ <show_in_store>1</show_in_store>
331
+ </suggest>
332
+ <recommendation translate="label">
333
+ <label>Enable FACT-Finder Recommendation</label>
334
+ <frontend_type>select</frontend_type>
335
+ <source_model>adminhtml/system_config_source_yesno</source_model>
336
+ <sort_order>30</sort_order>
337
+ <show_in_default>1</show_in_default>
338
+ <show_in_website>1</show_in_website>
339
+ <show_in_store>1</show_in_store>
340
+ </recommendation>
341
+ <tagcloud translate="label">
342
+ <label>Enable FACT-Finder Tag Cloud</label>
343
+ <frontend_type>select</frontend_type>
344
+ <source_model>adminhtml/system_config_source_yesno</source_model>
345
+ <sort_order>40</sort_order>
346
+ <show_in_default>1</show_in_default>
347
+ <show_in_website>1</show_in_website>
348
+ <show_in_store>1</show_in_store>
349
+ </tagcloud>
350
+ <tracking>
351
+ <label>Enable FACT-Finder Tracking</label>
352
+ <frontend_type>select</frontend_type>
353
+ <source_model>adminhtml/system_config_source_yesno</source_model>
354
+ <sort_order>50</sort_order>
355
+ <show_in_default>1</show_in_default>
356
+ <show_in_website>1</show_in_website>
357
+ <show_in_store>1</show_in_store>
358
+ </tracking>
359
+ <campaigns>
360
+ <label>Enable FACT-Finder Campaigns</label>
361
+ <frontend_type>select</frontend_type>
362
+ <source_model>adminhtml/system_config_source_yesno</source_model>
363
+ <sort_order>60</sort_order>
364
+ <show_in_default>1</show_in_default>
365
+ <show_in_website>1</show_in_website>
366
+ <show_in_store>1</show_in_store>
367
+ </campaigns>
368
+ </fields>
369
+ </modules>
370
+ </groups>
371
+ </factfinder>
372
+ <advanced>
373
+ <groups>
374
+ <ff_modules translate="label comment">
375
+ <label>Disable FACT-Finder Sub-Modules</label>
376
+ <comment><![CDATA[These settings allow to completely disable FACT-Finder sub-modules through changing xml files.<br />
377
+ To make this feature work the web-server should have the write permissions to the app/etc/modules directory]]></comment>
378
+ <sort_order>0</sort_order>
379
+ <show_in_default>1</show_in_default>
380
+ <show_in_website>0</show_in_website>
381
+ <show_in_store>0</show_in_store>
382
+ <fields>
383
+ <asn translate="label">
384
+ <label>FACT-Finder After Search Navigation</label>
385
+ <frontend_type>select</frontend_type>
386
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
387
+ <sort_order>10</sort_order>
388
+ <show_in_default>1</show_in_default>
389
+ <show_in_website>0</show_in_website>
390
+ <show_in_store>0</show_in_store>
391
+ </asn>
392
+ <suggest translate="label">
393
+ <label>FACT-Finder Suggest</label>
394
+ <frontend_type>select</frontend_type>
395
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
396
+ <sort_order>20</sort_order>
397
+ <show_in_default>1</show_in_default>
398
+ <show_in_website>0</show_in_website>
399
+ <show_in_store>0</show_in_store>
400
+ </suggest>
401
+ <recommendation translate="label">
402
+ <label>FACT-Finder Recommendation</label>
403
+ <frontend_type>select</frontend_type>
404
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
405
+ <sort_order>30</sort_order>
406
+ <show_in_default>1</show_in_default>
407
+ <show_in_website>0</show_in_website>
408
+ <show_in_store>0</show_in_store>
409
+ </recommendation>
410
+ <tagcloud translate="label">
411
+ <label>FACT-Finder Tag Cloud</label>
412
+ <frontend_type>select</frontend_type>
413
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
414
+ <sort_order>40</sort_order>
415
+ <show_in_default>1</show_in_default>
416
+ <show_in_website>0</show_in_website>
417
+ <show_in_store>0</show_in_store>
418
+ </tagcloud>
419
+ <tracking>
420
+ <label>FACT-Finder Tracking</label>
421
+ <frontend_type>select</frontend_type>
422
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
423
+ <sort_order>50</sort_order>
424
+ <show_in_default>1</show_in_default>
425
+ <show_in_website>0</show_in_website>
426
+ <show_in_store>0</show_in_store>
427
+ </tracking>
428
+ <campaigns>
429
+ <label>FACT-Finder Campaigns</label>
430
+ <frontend_type>select</frontend_type>
431
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
432
+ <sort_order>60</sort_order>
433
+ <show_in_default>1</show_in_default>
434
+ <show_in_website>0</show_in_website>
435
+ <show_in_store>0</show_in_store>
436
+ </campaigns>
437
+ </fields>
438
+ </ff_modules>
439
+ </groups>
440
+ </advanced>
441
+ </sections>
442
  </config>
app/code/community/FACTFinder/Recommendation/Helper/Data.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Recommendation
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Recommendation
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Recommendation_Helper_Data
16
+ *
17
+ * Default helper class
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Recommendation
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Recommendation_Helper_Data extends Mage_Core_Helper_Abstract
27
+ {
28
+
29
+ /**
30
+ * Check if import should be triggered for store
31
+ *
32
+ * @param int $storeId
33
+ *
34
+ * @return bool
35
+ */
36
+ public function shouldTriggerImport($storeId)
37
+ {
38
+ if (!Mage::getStoreConfigFlag('factfinder/modules/recommendation', $storeId)) {
39
+ return false;
40
+ }
41
+
42
+ return Mage::getStoreConfigFlag('factfinder/export/trigger_recommendation_import', $storeId);
43
+ }
44
+
45
+
46
+ }
app/code/community/FACTFinder/Recommendation/Model/Facade.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Recommendation
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Recommendation
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Recommendation_Model_Facade
16
+ *
17
+ * Facade class that adds recommendations functionality to the core facade
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Recommendation
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Recommendation_Model_Facade extends FACTFinder_Core_Model_Facade
27
+ {
28
+
29
+
30
+ /**
31
+ * Set config data to recommendations adaptor
32
+ *
33
+ * @param array $params
34
+ * @param string $channel
35
+ * @param int $id
36
+ *
37
+ * @return void
38
+ */
39
+ public function configureRecommendationAdapter($params, $channel = null, $id = null)
40
+ {
41
+ $this->_configureAdapter($params, "recommendation", $channel, $id);
42
+ }
43
+
44
+
45
+ /**
46
+ * Get recommendations array
47
+ *
48
+ * @param string $channel
49
+ * @param int $id
50
+ *
51
+ * @return ArrayIterator
52
+ */
53
+ public function getRecommendations($channel = null, $id = null)
54
+ {
55
+ return $this->_getFactFinderObject("recommendation", "getRecommendations", $channel, $id);
56
+ }
57
+
58
+
59
+ /**
60
+ * Trigger recommendations import on FF side
61
+ *
62
+ * @param null|string $channel
63
+ *
64
+ * @return SimpleXMLElement
65
+ */
66
+ public function triggerRecommendationImport($channel = null)
67
+ {
68
+ $this->configureImportAdapter(array('channel' => $channel));
69
+
70
+ return $this->getImportAdapter($channel)->triggerRecommendationImport(true);
71
+ }
72
+
73
+
74
+ }
app/code/community/FACTFinder/Recommendation/Model/Handler/Recommendations.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Recommendation
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Recommendation
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Recommendation_Model_Handler_Recommendations
16
+ *
17
+ * Handles product recommendation data
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Recommendation
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Recommendation_Model_Handler_Recommendations extends FACTFinder_Core_Model_Handler_Abstract
27
+ {
28
+
29
+ /**
30
+ * Array of product ids
31
+ *
32
+ * @var array
33
+ */
34
+ protected $_productIds = array();
35
+
36
+ /**
37
+ * Array of product ids
38
+ *
39
+ * @var array|null
40
+ */
41
+ protected $_recommendations;
42
+
43
+ /**
44
+ * Facade model to be used
45
+ *
46
+ * @var string
47
+ */
48
+ protected $_facadeModel = 'factfinder_recommendation/facade';
49
+
50
+
51
+ /**
52
+ * Class constructor
53
+ *
54
+ * @param array $productIds
55
+ */
56
+ public function __construct($productIds)
57
+ {
58
+ $this->_productIds = $productIds;
59
+ parent::__construct();
60
+ }
61
+
62
+
63
+ /**
64
+ * Set config values and configure adapter
65
+ *
66
+ * @return void
67
+ */
68
+ protected function _configureFacade()
69
+ {
70
+ $params = array();
71
+ $params['id'] = $this->_getIdParam();
72
+ $params['idsOnly'] = $this->_getFacade()->getConfiguration()->getIdsOnly() ? 'true' : 'false';
73
+ $this->_getFacade()->configureRecommendationAdapter($params);
74
+ }
75
+
76
+
77
+ /**
78
+ * Retrieve an array of recommendation result
79
+ *
80
+ * @return array|null
81
+ */
82
+ public function getRecommendations()
83
+ {
84
+ if ($this->_recommendations === null) {
85
+ $this->_recommendations = $this->_getFacade()->getRecommendations();
86
+ if ($this->_recommendations === null) {
87
+ Mage::helper('factfinder')->performFallbackRedirect();
88
+ }
89
+ }
90
+
91
+ return $this->_recommendations;
92
+ }
93
+
94
+
95
+ /**
96
+ * Get array of product ids for recommendations
97
+ *
98
+ * @return array
99
+ */
100
+ protected function _getIdParam()
101
+ {
102
+ if (is_array($this->_productIds)) {
103
+ return $this->_productIds;
104
+ } else {
105
+ return array($this->_productIds);
106
+ }
107
+ }
108
+
109
+
110
+ /**
111
+ * Get ids of recommended products
112
+ *
113
+ * @return array
114
+ */
115
+ public function getRecommendedIds()
116
+ {
117
+ $ids = array();
118
+ foreach ($this->getRecommendations() as $recommendation) {
119
+ $ids[] = $recommendation->getId();
120
+ }
121
+
122
+ return $ids;
123
+ }
124
+
125
+
126
+ }
app/code/community/FACTFinder/Recommendation/Model/Observer.php ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Recommendation
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Recommendation
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Class FACTFinder_Recommendation_Model_Observer
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Recommendation
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Recommendation_Model_Observer
25
+ {
26
+
27
+
28
+ /**
29
+ * Loads recommended items within upsell\cross-sell collection
30
+ *
31
+ * @param Varien_Object $observer
32
+ *
33
+ * @return void
34
+ */
35
+ public function loadRecommendedItemsItems($observer)
36
+ {
37
+ if (!Mage::helper('factfinder')->isEnabled('recommendation')) {
38
+ return;
39
+ }
40
+
41
+ $collection = $observer->getCollection();
42
+
43
+ $availableTypes = array(
44
+ Mage_Catalog_Model_Product_Link::LINK_TYPE_UPSELL,
45
+ Mage_Catalog_Model_Product_Link::LINK_TYPE_CROSSSELL,
46
+ );
47
+ if (!$collection instanceof Mage_Catalog_Model_Resource_Product_Link_Product_Collection
48
+ || !in_array($collection->getLinkModel()->getLinkTypeId(), $availableTypes)
49
+ ) {
50
+ return;
51
+ }
52
+
53
+ $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
54
+
55
+ $ids = $this->_getProductIds($collection, $idFieldName);
56
+ $this->_processCollection($collection, $ids, $idFieldName);
57
+
58
+ }
59
+
60
+
61
+ /**
62
+ * Remove all not needed and add all the necessary filter to the product collection
63
+ *
64
+ * @param Mage_Catalog_Model_Resource_Product_Link_Product_Collection $collection
65
+ * @param array $productIds
66
+ * @param string $idFieldName
67
+ *
68
+ * @return FACTFinder_Recommendation_Model_Observer
69
+ */
70
+ protected function _processCollection($collection, $productIds, $idFieldName)
71
+ {
72
+ $select = $collection->getSelect();
73
+
74
+ $linkParts = array('links', 'link_attribute_position_int');
75
+
76
+ // remove link parts from from
77
+ $from = $select->getPart(Zend_Db_Select::FROM);
78
+ foreach ($linkParts as $linkPart) {
79
+ unset($from[$linkPart]);
80
+ }
81
+
82
+ $select->setPart(Zend_Db_Select::FROM, $from);
83
+
84
+ // reset all where conditions
85
+ $select->reset(Zend_Db_Select::WHERE);
86
+
87
+ // remove link part from columns
88
+ $columns = $select->getPart(Zend_Db_Select::COLUMNS);
89
+ foreach ($columns as $index => $column) {
90
+ if (in_array($column[0], $linkParts)) {
91
+ unset($columns[$index]);
92
+ }
93
+ }
94
+
95
+ $select->setPart(Zend_Db_Select::COLUMNS, $columns);
96
+
97
+ $handler = Mage::getModel('factfinder_recommendation/handler_recommendations', $productIds);
98
+ $recommendations = $handler->getRecommendedIds();
99
+
100
+ if ($recommendations) {
101
+ $collection->addAttributeToFilter($idFieldName, array('in' => $recommendations));
102
+
103
+ $order = new Zend_Db_Expr($collection->getConnection()->quoteInto(
104
+ 'find_in_set(`e`.`' . $idFieldName . '`, ?)',
105
+ implode(',', $recommendations)
106
+ ));
107
+ $select->order($order);
108
+ } else {
109
+ // do not load anything
110
+ $collection->addAttributeToFilter($idFieldName, array('in' => array(-1)));
111
+ }
112
+
113
+ return $this;
114
+ }
115
+
116
+
117
+ /**
118
+ * Get current product ids
119
+ *
120
+ * @param Mage_Catalog_Model_Resource_Product_Link_Product_Collection $collection
121
+ * @param string $idFieldName
122
+ *
123
+ * @return array
124
+ */
125
+ protected function _getProductIds($collection, $idFieldName)
126
+ {
127
+ if ($collection->getProduct() && $collection->getProduct()->getId()) {
128
+ return array($collection->getProduct()->getData($idFieldName));
129
+ }
130
+
131
+ $ids = array();
132
+
133
+ $product = Mage::registry('product');
134
+ if ($product instanceof Mage_Catalog_Model_Product) {
135
+ $ids[] = $product->getData($idFieldName);
136
+ }
137
+
138
+ if ($collection->getLinkModel()->getLinkTypeId() == Mage_Catalog_Model_Product_Link::LINK_TYPE_CROSSSELL) {
139
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
140
+ foreach ($quote->getAllItems() as $item) {
141
+ if ($product = $item->getProduct()) {
142
+ $ids[] = $product->getData($idFieldName);
143
+ }
144
+ }
145
+ }
146
+
147
+ return $ids;
148
+ }
149
+
150
+
151
+ /**
152
+ * @param Varien_Object $observer
153
+ *
154
+ * @return void
155
+ */
156
+ public function triggerImportAfterExport($observer)
157
+ {
158
+ $storeId = $observer->getStoreId();
159
+ if (Mage::helper('factfinder_recommendation')->shouldTriggerImport($storeId)) {
160
+ foreach (Mage::helper('factfinder')->getStoreChannels($storeId) as $channel) {
161
+ $facade = Mage::getModel('factfinder_recommendation/facade');
162
+ $facade->triggerRecommendationImport($channel);
163
+ }
164
+ }
165
+ }
166
+
167
+
168
+ }
app/code/community/FACTFinder/Recommendation/etc/config.xml ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Recommendation
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Recommendation
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <config>
15
+ <modules>
16
+ <FACTFinder_Recommendation>
17
+ <version>4.0.1</version>
18
+ </FACTFinder_Recommendation>
19
+ </modules>
20
+ <global>
21
+ <models>
22
+ <factfinder_recommendation>
23
+ <class>FACTFinder_Recommendation_Model</class>
24
+ </factfinder_recommendation>
25
+ </models>
26
+ <blocks>
27
+ <factfinder_recommendation>
28
+ <class>FACTFinder_Recommendation_Block</class>
29
+ </factfinder_recommendation>
30
+ </blocks>
31
+ <helpers>
32
+ <factfinder_recommendation>
33
+ <class>FACTFinder_Recommendation_Helper</class>
34
+ </factfinder_recommendation>
35
+ </helpers>
36
+ <events>
37
+ <factfinder_export_after>
38
+ <observers>
39
+ <factfinder_recommendation_import>
40
+ <class>factfinder_recommendation/observer</class>
41
+ <method>triggerImportAfterExport</method>
42
+ </factfinder_recommendation_import>
43
+ </observers>
44
+ </factfinder_export_after>
45
+ </events>
46
+ </global>
47
+ <frontend>
48
+ <events>
49
+ <catalog_product_collection_load_before>
50
+ <observers>
51
+ <factfinder_recommendation_load_upsell>
52
+ <class>factfinder_recommendation/observer</class>
53
+ <method>loadRecommendedItemsItems</method>
54
+ </factfinder_recommendation_load_upsell>
55
+ </observers>
56
+ </catalog_product_collection_load_before>
57
+ </events>
58
+ </frontend>
59
+ </config>
app/code/community/FACTFinder/Recommendation/etc/system.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <factfinder>
5
+ <groups>
6
+ <export>
7
+ <fields>
8
+ <trigger_recommendation_import translate="label">
9
+ <label>Trigger Recommendation Import</label>
10
+ <frontend_type>select</frontend_type>
11
+ <source_model>adminhtml/system_config_source_yesno</source_model>
12
+ <sort_order>90</sort_order>
13
+ <show_in_default>1</show_in_default>
14
+ <show_in_website>1</show_in_website>
15
+ <show_in_store>1</show_in_store>
16
+ <comment><![CDATA[Start FACTFinder recommendation import after each export]]></comment>
17
+ </trigger_recommendation_import>
18
+ </fields>
19
+ </export>
20
+ </groups>
21
+ </factfinder>
22
+ </sections>
23
+ </config>
app/code/community/FACTFinder/Suggest/Block/TopSearch.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Block class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Suggest
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Suggest_Block_TopSearch extends Mage_Core_Block_Template
25
+ {
26
+
27
+
28
+ /**
29
+ * Get suggect translatyion in json encoded format
30
+ *
31
+ * @return string
32
+ */
33
+ public function getTranslationsAsJson()
34
+ {
35
+ $channels = explode(';', Mage::getStoreConfig('factfinder/search/secondary_channels'));
36
+ $result = new StdClass();
37
+
38
+ foreach($channels as $channel) {
39
+ $result->{'Channel: ' . $channel} = $this->__('Channel: ' . $channel);
40
+ }
41
+
42
+ $result->{'searchTerm'} = $this->__('ff_searchTerm');
43
+ $result->{'category'} = $this->__('ff_category');
44
+ $result->{'productName'} = $this->__('ff_productName');
45
+
46
+ return json_encode($result);
47
+ }
48
+
49
+
50
+ }
app/code/community/{Flagbit/FactFinder → FACTFinder/Suggest}/Block/XmlConnect/Catalog/Search/Suggest.php RENAMED
@@ -1,58 +1,65 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * This class enables FAC-Finder sugguest
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_XmlConnect_Catalog_Search_Suggest extends Mage_XmlConnect_Block_Catalog_Search_Suggest
22
- {
23
- const SUGGEST_ITEM_SEPARATOR = '::sep::';
24
-
25
- /**
26
- * Search suggestions xml renderer
27
- *
28
- * @return string
29
- */
30
- protected function _toHtml()
31
- {
32
- $suggestXmlObj = new Mage_XmlConnect_Model_Simplexml_Element('<suggestions></suggestions>');
33
- if (!$this->getRequest()->getParam('q', false)) {
34
- return $suggestXmlObj->asNiceXml();
35
- }
36
-
37
- $handler = Mage::getSingleton('factfinder/handler_suggest', array($this->getRequest()->getParam('q')));
38
-
39
- $suggestData = $handler->getSuggestionsAsArray();
40
-
41
- if (!($count = count($suggestData))) {
42
- return $suggestXmlObj->asNiceXml();
43
- }
44
-
45
- $items = '';
46
- foreach ($suggestData as $index => $item) {
47
- $items .= $suggestXmlObj->xmlentities(strip_tags($item['query']))
48
- . self::SUGGEST_ITEM_SEPARATOR
49
- . (int)$item['hitCount']
50
- . self::SUGGEST_ITEM_SEPARATOR;
51
- }
52
-
53
- $suggestXmlObj = new Mage_XmlConnect_Model_Simplexml_Element('<suggestions>' . $items . '</suggestions>');
54
-
55
- return $suggestXmlObj->asNiceXml();
56
- }
57
-
58
- }
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Block class
16
+ *
17
+ * This class enables FAC-Finder suggest
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Suggest
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class Flagbit_FactFinder_Block_XmlConnect_Catalog_Search_Suggest extends Mage_XmlConnect_Block_Catalog_Search_Suggest
27
+ {
28
+ const SUGGEST_ITEM_SEPARATOR = '::sep::';
29
+
30
+
31
+ /**
32
+ * Search suggestions xml renderer
33
+ *
34
+ * @return string
35
+ */
36
+ protected function _toHtml()
37
+ {
38
+ $suggestXmlObj = new Mage_XmlConnect_Model_Simplexml_Element('<suggestions></suggestions>');
39
+ if (!$this->getRequest()->getParam('q', false)) {
40
+ return $suggestXmlObj->asNiceXml();
41
+ }
42
+
43
+ $handler = Mage::getSingleton('factfinder_suggest/handler_suggest', array($this->getRequest()->getParam('q')));
44
+
45
+ $suggestData = $handler->getSuggestionsAsArray();
46
+
47
+ if (!($count = count($suggestData))) {
48
+ return $suggestXmlObj->asNiceXml();
49
+ }
50
+
51
+ $items = '';
52
+ foreach ($suggestData as $index => $item) {
53
+ $items .= $suggestXmlObj->xmlentities(strip_tags($item['query']))
54
+ . self::SUGGEST_ITEM_SEPARATOR
55
+ . (int) $item['hitCount']
56
+ . self::SUGGEST_ITEM_SEPARATOR;
57
+ }
58
+
59
+ $suggestXmlObj = new Mage_XmlConnect_Model_Simplexml_Element('<suggestions>' . $items . '</suggestions>');
60
+
61
+ return $suggestXmlObj->asNiceXml();
62
+ }
63
+
64
+
65
+ }
app/code/community/FACTFinder/Suggest/Helper/Data.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Suggest
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Suggest_Helper_Data extends Mage_Core_Helper_Abstract
25
+ {
26
+
27
+ const XML_CONFIG_PATH_USE_PROXY = 'factfinder/config/proxy';
28
+
29
+
30
+ /**
31
+ * Get FACT-Finder Suggest URL
32
+ *
33
+ * @return string
34
+ */
35
+ public function getSuggestUrl()
36
+ {
37
+ if ($this->isSuggestProxyActivated()) {
38
+ $params = array();
39
+ if (Mage::app()->getStore()->isCurrentlySecure()) {
40
+ $params['_secure'] = true;
41
+ }
42
+
43
+ $url = $this->_getUrl('factfinder_suggest/proxy/suggest', $params);
44
+ } else {
45
+ $url = Mage::getSingleton('factfinder_suggest/facade')->getSuggestUrl();
46
+ if (Mage::app()->getStore()->isCurrentlySecure()) {
47
+ $url = preg_replace('/^http:/', 'https:', $url);
48
+ }
49
+ }
50
+
51
+ return $url;
52
+ }
53
+
54
+
55
+ /**
56
+ * Check config is proxy is activated
57
+ *
58
+ * @return bool
59
+ */
60
+ public function isSuggestProxyActivated()
61
+ {
62
+ return Mage::getStoreConfig(self::XML_CONFIG_PATH_USE_PROXY);
63
+ }
64
+
65
+
66
+ /**
67
+ * Check if import should be triggered for store
68
+ *
69
+ * @param int $storeId
70
+ *
71
+ * @return bool
72
+ */
73
+ public function shouldTriggerImport($storeId)
74
+ {
75
+ if (!Mage::getStoreConfigFlag('factfinder/modules/suggest', $storeId)) {
76
+ return false;
77
+ }
78
+
79
+ return Mage::getStoreConfigFlag('factfinder/export/trigger_suggest_import', $storeId);
80
+ }
81
+
82
+
83
+ }
app/code/community/FACTFinder/Suggest/Model/Facade.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Suggest
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Suggest_Model_Facade extends FACTFinder_Core_Model_Facade
25
+ {
26
+
27
+
28
+ /**
29
+ * Set config data to suggest adapter
30
+ *
31
+ * @param array $params
32
+ * @param string $channel
33
+ * @param int $id
34
+ */
35
+ public function configureSuggestAdapter($params, $channel = null, $id = null)
36
+ {
37
+ $this->_configureAdapter($params, "suggest", $channel, $id);
38
+ }
39
+
40
+
41
+ /**
42
+ * Get suggestions object from adapter
43
+ *
44
+ * @param string $channel
45
+ * @param int $id
46
+ *
47
+ * @return Object
48
+ */
49
+ public function getSuggestions($channel = null, $id = null)
50
+ {
51
+ return $this->_getFactFinderObject("suggest", "getSuggestions", $channel, $id);
52
+ }
53
+
54
+
55
+ /**
56
+ * Get url to access ff api
57
+ *
58
+ * @return string
59
+ */
60
+ public function getSuggestUrl()
61
+ {
62
+ return $this->_getUrlBuilder()
63
+ ->getNonAuthenticationUrl('Suggest.ff', $this->_dic['requestParser']->getRequestParameters());
64
+ }
65
+
66
+
67
+ /**
68
+ * Trigger suggest import on FF side
69
+ *
70
+ * @param null|string $channel
71
+ *
72
+ * @return SimpleXMLElement
73
+ */
74
+ public function triggerSuggestImport($channel = null)
75
+ {
76
+ $this->configureImportAdapter(array('channel' => $channel));
77
+
78
+ return $this->getImportAdapter($channel)->triggerSuggestImport(true);
79
+ }
80
+
81
+
82
+ }
app/code/community/FACTFinder/Suggest/Model/Handler/Suggest.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * Handles Suggest data
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Suggest
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Suggest_Model_Handler_Suggest extends FACTFinder_Core_Model_Handler_Abstract
27
+ {
28
+
29
+ protected $_query;
30
+
31
+ protected $_jqueryCallback;
32
+
33
+ protected $_suggestResult;
34
+
35
+ protected $_suggestResultAsArray;
36
+
37
+ protected $_primaryChannel;
38
+
39
+ protected $_secondaryChannels;
40
+
41
+ /**
42
+ * Facade model to use
43
+ *
44
+ * @var string
45
+ */
46
+ protected $_facadeModel = 'factfinder_suggest/facade';
47
+
48
+
49
+ /**
50
+ * We might need to supply the facade manually, because we might not have a full Magento
51
+ * context and we cannot call Mage::getSingleton().
52
+ * @param string $query
53
+ * @param string $jqueryCallback
54
+ * @param FACTFinder_Suggest_Model_Facade $facade
55
+ */
56
+ public function __construct($query, $jqueryCallback = '', $facade = null)
57
+ {
58
+ $this->_facade = $facade;
59
+ $this->_query = $query;
60
+
61
+ // prevent xss (<script> tags can open a vulnerability)
62
+ $this->_jqueryCallback = strip_tags($jqueryCallback);
63
+
64
+ parent::__construct();
65
+ }
66
+
67
+
68
+ /**
69
+ * Set config params to the adapter
70
+ *
71
+ * @return void
72
+ */
73
+ protected function _configureFacade()
74
+ {
75
+ $params = array();
76
+ $params['format'] = 'json';
77
+ $params['query'] = $this->_query;
78
+
79
+ $this->_primaryChannel = $this->_getFacade()->getConfiguration()->getChannel();
80
+ $this->_secondaryChannels = $this->_getFacade()->getConfiguration()->getSecondaryChannels();
81
+
82
+ $this->_getFacade()->configureSuggestAdapter($params);
83
+ }
84
+
85
+
86
+ /**
87
+ * Get suggestions as string
88
+ *
89
+ * @return string
90
+ */
91
+ public function getSuggestions()
92
+ {
93
+ if ($this->_suggestResult === null) {
94
+ $this->_suggestResult = $this->_assembleSuggestResult();
95
+ }
96
+
97
+ return $this->_suggestResult;
98
+ }
99
+
100
+
101
+ /**
102
+ * Retrieve suggestions array
103
+ *
104
+ * @return array
105
+ */
106
+ public function getSuggestionsAsArray()
107
+ {
108
+ if ($this->_suggestResultAsArray === null) {
109
+ $this->_suggestResultAsArray = $this->_assembleSuggestResultAsArray();
110
+ }
111
+
112
+ return $this->_suggestResultAsArray;
113
+ }
114
+
115
+
116
+ /**
117
+ * Encode suggest result to json
118
+ *
119
+ * @return string
120
+ */
121
+ protected function _assembleSuggestResult()
122
+ {
123
+ // Retrieve and merge all suggestions
124
+ // Add a new "channel" field in the process
125
+
126
+ $suggestResult = $this->_getAndSanitizeSuggestions();
127
+
128
+ foreach ($this->_secondaryChannels AS $channel) {
129
+ $params = array('channel' => $channel);
130
+ $this->_getFacade()->configureSuggestAdapter($params, $channel);
131
+
132
+ $result = $this->_getAndSanitizeSuggestions($channel);
133
+ $suggestResult = array_merge($suggestResult, $result);
134
+ }
135
+
136
+ $resultArray = array();
137
+ foreach ($suggestResult as $resultQuery) {
138
+ /** @var $resultQuery FACTFinder\Data\SuggestQuery */
139
+ $resultArray['suggestions'][] = array(
140
+ 'attributes' => $resultQuery->getAttributes(),
141
+ 'hitCount' => $resultQuery->getHitCount(),
142
+ 'image' => $resultQuery->getImageUrl(),
143
+ 'searchParams' => $resultQuery->getUrl(),
144
+ 'type' => $resultQuery->getType(),
145
+ 'name' => $resultQuery->getLabel(),
146
+ 'channel' => $resultQuery->channel
147
+ );
148
+ }
149
+
150
+ return $this->_jqueryCallback . '(' . Zend_Json_Encoder::encode($resultArray) . ');';
151
+ }
152
+
153
+
154
+ /**
155
+ * Decode suggest result from json to array
156
+ *
157
+ * @return mixed
158
+ *
159
+ * @throws \Zend_Json_Exception
160
+ */
161
+ protected function _assembleSuggestResultAsArray()
162
+ {
163
+ // TODO: Multiple channels
164
+ return Zend_Json_Decoder::decode($this->_getAndSanitizeSuggestions());
165
+ }
166
+
167
+
168
+ /**
169
+ * Get sanitazed string of suggestions
170
+ *
171
+ * @param string $channel
172
+ *
173
+ * @return string
174
+ */
175
+ protected function _getAndSanitizeSuggestions($channel = null)
176
+ {
177
+ $result = $this->_getFacade()->getSuggestions($channel);
178
+ if ($result === null) {
179
+ $result = '';
180
+ }
181
+
182
+ if (is_array($result)) {
183
+ foreach ($result as $item) {
184
+ $item->channel = $channel ? $channel : $this->_primaryChannel;
185
+ }
186
+ }
187
+
188
+ return $result;
189
+ }
190
+
191
+
192
+ }
app/code/community/FACTFinder/Suggest/Model/Observer.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Suggest
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Suggest_Model_Observer
25
+ {
26
+
27
+
28
+ /**
29
+ * Add suggest handle to the layout
30
+ *
31
+ * @param Varien_Object $observer
32
+ *
33
+ * @return void
34
+ */
35
+ public function addSuggestHandles($observer)
36
+ {
37
+ if (!Mage::helper('factfinder')->isEnabled('suggest')) {
38
+ return;
39
+ }
40
+
41
+ $layout = $observer->getLayout();
42
+ $update = $layout->getUpdate();
43
+ $update->addHandle('factfinder_suggest_enabled');
44
+ }
45
+
46
+
47
+ /**
48
+ * @param Varien_Object $observer
49
+ *
50
+ * @return void
51
+ */
52
+ public function triggerImportAfterExport($observer)
53
+ {
54
+ $storeId = $observer->getStoreId();
55
+ if (Mage::helper('factfinder_suggest')->shouldTriggerImport($storeId)) {
56
+ foreach (Mage::helper('factfinder')->getStoreChannels($storeId) as $channel) {
57
+ $facade = Mage::getModel('factfinder_suggest/facade');
58
+ $facade->triggerSuggestImport($channel);
59
+ }
60
+ }
61
+ }
62
+
63
+
64
+ }
app/code/community/FACTFinder/Suggest/Model/Processor.php ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ require_once BP . DS . 'lib' . DS . 'FACTFinder' . DS . 'Loader.php';
15
+
16
+ /**
17
+ * Model class
18
+ *
19
+ * Request Processor for fast handling
20
+ *
21
+ * @category Mage
22
+ * @package FACTFinder_Suggest
23
+ * @author Flagbit Magento Team <magento@flagbit.de>
24
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @link http://www.flagbit.de
27
+ */
28
+ class FACTFinder_Suggest_Model_Processor
29
+ {
30
+
31
+ const CACHE_TAG = 'FACTFINDER'; // Cache Tag
32
+ const REQUEST_ID_PREFIX = 'FACTFINDER_';
33
+ const XML_CONFIG_PATH = 'factfinder/search/';
34
+
35
+ /**
36
+ * FactFinder Facade
37
+ *
38
+ * @var FACTFinder_Core_Model_Facade
39
+ */
40
+ protected $_facade;
41
+
42
+
43
+ /**
44
+ * Class constructor
45
+ */
46
+ public function __construct()
47
+ {
48
+ $uri = $this->_getFullPageUrl();
49
+
50
+ $this->_initFFAutoloader();
51
+
52
+ $this->_requestId = $uri;
53
+ $this->_requestCacheId = $this->prepareCacheId($this->_requestId);
54
+ $this->_requestTags = array(self::CACHE_TAG);
55
+ }
56
+
57
+
58
+ /**
59
+ * Init fact-finder lib autoloader
60
+ *
61
+ * @return void
62
+ */
63
+ protected function _initFFAutoloader()
64
+ {
65
+ $autoloaderClass = new FACTFinder_Core_Model_Autoloader();
66
+ $autoloaderClass->addAutoloader(new Varien_Event_Observer());
67
+ }
68
+
69
+
70
+ /**
71
+ * Get Fact-Finder Facade
72
+ * we do it manually, because we do not have the full magento context
73
+ *
74
+ * @param mixed $config
75
+ *
76
+ * @return FACTFinder_Core_Model_Facade
77
+ */
78
+ protected function _getFacade($config = null)
79
+ {
80
+ if ($this->_facade === null) {
81
+ $logger = new FACTFinder_Core_Helper_Debug();
82
+ $this->_facade = new FACTFinder_Suggest_Model_Facade($logger, $config);
83
+ }
84
+
85
+ return $this->_facade;
86
+ }
87
+
88
+
89
+ /**
90
+ * Get page content from cache storage
91
+ *
92
+ * @param string $content
93
+ *
94
+ * @return string|false
95
+ */
96
+ public function extractContent($content)
97
+ {
98
+ // handle in App Request if "ff_suggest" in Request path
99
+ if (empty($content)
100
+ && strpos($this->_requestId, 'ff_suggest')
101
+ && $this->isAllowed()
102
+ ) {
103
+ $requestCacheId = $this->prepareCacheId($this->getRequestId() . 'request');
104
+ $request = Mage::app()->loadCache($requestCacheId);
105
+ if ($request) {
106
+ $content = $this->handleWithoutAppRequest();
107
+ }
108
+ }
109
+
110
+ return $content;
111
+ }
112
+
113
+
114
+ /**
115
+ * handle in App Requests
116
+ *
117
+ * @param string $request
118
+ *
119
+ * @return string
120
+ */
121
+ public function handleInAppRequest($request)
122
+ {
123
+ $requestCacheId = $this->prepareCacheId($this->getRequestId() . 'request');
124
+ Mage::app()->saveCache($request, $requestCacheId, $this->getRequestTags());
125
+
126
+ $configCacheId = $this->prepareCacheId($this->getRequestId() . 'config');
127
+ Mage::app()->saveCache(
128
+ serialize(Mage::getStoreConfig('factfinder/search')),
129
+ $configCacheId, $this->getRequestTags()
130
+ );
131
+
132
+ return $this->_handleRequest();
133
+ }
134
+
135
+
136
+ /**
137
+ * Hanlde without App Requests
138
+ *
139
+ * @return string
140
+ */
141
+ public function handleWithoutAppRequest()
142
+ {
143
+ $configCacheId = $this->prepareCacheId($this->getRequestId() . 'config');
144
+ $config = null;
145
+
146
+ try {
147
+ $config = unserialize(Mage::app()->loadCache($configCacheId));
148
+ } catch (Exception $e) {
149
+ return '';
150
+ }
151
+
152
+ if (!is_array($config) || empty($config)) {
153
+ return '';
154
+ }
155
+
156
+ $this->_getFacade($config);
157
+
158
+ return $this->_handleRequest();
159
+ }
160
+
161
+
162
+ /**
163
+ * Handle Requests
164
+ *
165
+ * @return string
166
+ */
167
+ protected function _handleRequest()
168
+ {
169
+ $handler = new FACTFinder_Suggest_Model_Handler_Suggest(
170
+ $this->_getRequestParam('query'),
171
+ $this->_getRequestParam('jquery_callback'),
172
+ $this->_getFacade()
173
+ );
174
+
175
+ return $handler->getSuggestions();
176
+ }
177
+
178
+
179
+ /**
180
+ * Get Request Param by Key
181
+ *
182
+ * @param string $key
183
+ *
184
+ * @return string
185
+ */
186
+ protected function _getRequestParam($key)
187
+ {
188
+ $value = null;
189
+ if (isset($_REQUEST[$key])) {
190
+ $value = $_REQUEST[$key];
191
+ }
192
+
193
+ return $value;
194
+ }
195
+
196
+
197
+ /**
198
+ * Return current page base url
199
+ *
200
+ * @return string
201
+ */
202
+ protected function _getFullPageUrl()
203
+ {
204
+ $uri = false;
205
+ /**
206
+ * Define server HTTP HOST
207
+ */
208
+ if (isset($_SERVER['HTTP_HOST'])) {
209
+ $uri = $_SERVER['HTTP_HOST'];
210
+ } elseif (isset($_SERVER['SERVER_NAME'])) {
211
+ $uri = $_SERVER['SERVER_NAME'];
212
+ }
213
+
214
+ /**
215
+ * Define request URI
216
+ */
217
+ if ($uri) {
218
+ if (isset($_SERVER['REQUEST_URI'])) {
219
+ $uri .= $_SERVER['REQUEST_URI'];
220
+ } elseif (!empty($_SERVER['IIS_WasUrlRewritten']) && !empty($_SERVER['UNENCODED_URL'])) {
221
+ $uri .= $_SERVER['UNENCODED_URL'];
222
+ } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
223
+ $uri .= $_SERVER['ORIG_PATH_INFO'];
224
+ if (!empty($_SERVER['QUERY_STRING'])) {
225
+ $uri .= $_SERVER['QUERY_STRING'];
226
+ }
227
+ }
228
+ }
229
+
230
+ $pieces = explode('?', $uri);
231
+ $uri = array_shift($pieces);
232
+
233
+ return $uri;
234
+ }
235
+
236
+
237
+ /**
238
+ * Prepare page identifier
239
+ *
240
+ * @param string $id
241
+ *
242
+ * @return string
243
+ */
244
+ public function prepareCacheId($id)
245
+ {
246
+ return self::REQUEST_ID_PREFIX . md5($id);
247
+ }
248
+
249
+
250
+ /**
251
+ * Get HTTP request identifier
252
+ *
253
+ * @return string
254
+ */
255
+ public function getRequestId()
256
+ {
257
+ return $this->_requestId . (isset($_COOKIE['store']) ? $_COOKIE['store'] : '');
258
+ }
259
+
260
+
261
+ /**
262
+ * Get page identifier for loading page from cache
263
+ *
264
+ * @return string
265
+ */
266
+ public function getRequestCacheId()
267
+ {
268
+ return $this->_requestCacheId;
269
+ }
270
+
271
+
272
+ /**
273
+ * Check if processor is allowed for current HTTP request.
274
+ * Disable processing HTTPS requests and requests with "NO_CACHE" cookie
275
+ *
276
+ * @return bool
277
+ */
278
+ public function isAllowed()
279
+ {
280
+ if (!$this->_requestId
281
+ || isset($_COOKIE['NO_CACHE'])
282
+ || isset($_GET['no_cache'])
283
+ ) {
284
+ return false;
285
+ }
286
+
287
+ return true;
288
+ }
289
+
290
+
291
+ /**
292
+ * Get cache request associated tags
293
+ *
294
+ * @return array
295
+ */
296
+ public function getRequestTags()
297
+ {
298
+ return $this->_requestTags;
299
+ }
300
+
301
+
302
+ }
app/code/community/FACTFinder/Suggest/Model/System/Config/Source/Imagetype.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * Image type source model
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_Suggest
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Suggest_Model_System_Config_Source_Imagetype
27
+ {
28
+
29
+
30
+ /**
31
+ * Get available image types
32
+ *
33
+ * @return array
34
+ */
35
+ public function toOptionArray()
36
+ {
37
+ $options = array();
38
+ foreach (Mage::getModel('catalog/product')->getMediaAttributes() as $key => $value) {
39
+ $options[] = array(
40
+ 'label' => $value->getFrontendLabel(),
41
+ 'value' => $key
42
+ );
43
+ }
44
+
45
+ return $options;
46
+ }
47
+
48
+
49
+ }
50
+
app/code/community/FACTFinder/Suggest/controllers/ProxyController.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Controller class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Suggest
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Suggest_ProxyController extends Mage_Core_Controller_Front_Action
25
+ {
26
+
27
+
28
+ /**
29
+ * Suggest Action
30
+ */
31
+ public function suggestAction()
32
+ {
33
+ if (!Mage::helper('factfinder')->isEnabled('suggest')) {
34
+ return;
35
+ }
36
+
37
+ $this->getResponse()->setHeader("Content-Type", "application/json;charset=utf-8", true);
38
+ $this->getResponse()->setBody(
39
+ Mage::getModel('factfinder_suggest/processor')->handleInAppRequest($this->getFullActionName())
40
+ );
41
+ }
42
+
43
+
44
+ }
app/code/community/FACTFinder/Suggest/etc/config.xml ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Suggest
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Suggest
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <modules>
17
+ <FACTFinder_Suggest>
18
+ <version>4.0.1</version>
19
+ </FACTFinder_Suggest>
20
+ </modules>
21
+ <global>
22
+ <models>
23
+ <factfinder_suggest>
24
+ <class>FACTFinder_Suggest_Model</class>
25
+ </factfinder_suggest>
26
+ </models>
27
+ <blocks>
28
+ <factfinder_suggest>
29
+ <class>FACTFinder_Suggest_Block</class>
30
+ </factfinder_suggest>
31
+ <xmlconnect>
32
+ <rewrite>
33
+ <catalog_search_suggest>FACTFinder_Suggest_Block_XmlConnect_Catalog_Search_Suggest</catalog_search_suggest>
34
+ </rewrite>
35
+ </xmlconnect>
36
+ </blocks>
37
+ <helpers>
38
+ <factfinder_suggest>
39
+ <class>FACTFinder_Suggest_Helper</class>
40
+ </factfinder_suggest>
41
+ </helpers>
42
+ <events>
43
+ <factfinder_export_after>
44
+ <observers>
45
+ <factfinder_suggest_import>
46
+ <class>factfinder_suggest/observer</class>
47
+ <method>triggerImportAfterExport</method>
48
+ </factfinder_suggest_import>
49
+ </observers>
50
+ </factfinder_export_after>
51
+ </events>
52
+ </global>
53
+ <frontend>
54
+ <routers>
55
+ <factfinder_suggest>
56
+ <use>standard</use>
57
+ <args>
58
+ <module>FACTFinder_Suggest</module>
59
+ <frontName>ff_suggest</frontName>
60
+ </args>
61
+ </factfinder_suggest>
62
+ </routers>
63
+ <events>
64
+ <controller_action_layout_load_before>
65
+ <observers>
66
+ <addActivationLayoutHandles>
67
+ <class>factfinder_suggest/observer</class>
68
+ <method>addSuggestHandles</method>
69
+ </addActivationLayoutHandles>
70
+ </observers>
71
+ </controller_action_layout_load_before>
72
+ </events>
73
+ <layout>
74
+ <updates>
75
+ <factfinder_suggest>
76
+ <file>factfinder/suggest.xml</file>
77
+ </factfinder_suggest>
78
+ </updates>
79
+ </layout>
80
+ <translate>
81
+ <modules>
82
+ <FACTFinder_Suggest>
83
+ <files>
84
+ <default>FACTFinder_Suggest.csv</default>
85
+ </files>
86
+ </FACTFinder_Suggest>
87
+ </modules>
88
+ </translate>
89
+ </frontend>
90
+ <default>
91
+ <factfinder>
92
+ <config>
93
+ <proxy>1</proxy>
94
+ </config>
95
+ </factfinder>
96
+ </default>
97
+ </config>
app/code/community/FACTFinder/Suggest/etc/system.xml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Suggest
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Suggest
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <sections>
17
+ <factfinder>
18
+ <groups>
19
+ <search>
20
+ <fields>
21
+ <secondary_channels translate="label">
22
+ <label>Secondary Channels</label>
23
+ <comment>Enter any secondary channels you want to search. Multiple channels should be separated by semicolons. NOTE: Secondary channels will only be considered for Suggest results if the proxy is used (see option in section "FACT-Finder Config Data")!</comment>
24
+ <frontend_type>text</frontend_type>
25
+ <sort_order>75</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>1</show_in_website>
28
+ <show_in_store>1</show_in_store>
29
+ </secondary_channels>
30
+ </fields>
31
+ </search>
32
+ <export>
33
+ <fields>
34
+ <urls translate="label">
35
+ <label>Export Images and Deeplinks</label>
36
+ <frontend_type>select</frontend_type>
37
+ <source_model>adminhtml/system_config_source_yesno</source_model>
38
+ <sort_order>10</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </urls>
43
+ <suggest_image_size translate="label comment">
44
+ <label>Size of Suggest images</label>
45
+ <comment>Please enter the desired edge length of the Suggest images in pixels. If you do not want them to be resized, enter 0.</comment>
46
+ <frontend_type>text</frontend_type>
47
+ <sort_order>15</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
+ </suggest_image_size>
52
+ <suggest_image_type translate="label">
53
+ <label>Type of Suggest images</label>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>factfinder_suggest/system_config_source_imagetype</source_model>
56
+ <sort_order>16</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <show_in_website>1</show_in_website>
59
+ <show_in_store>1</show_in_store>
60
+ </suggest_image_type>
61
+ <trigger_suggest_import translate="label">
62
+ <label>Trigger Suggest Import</label>
63
+ <frontend_type>select</frontend_type>
64
+ <source_model>adminhtml/system_config_source_yesno</source_model>
65
+ <sort_order>80</sort_order>
66
+ <show_in_default>1</show_in_default>
67
+ <show_in_website>1</show_in_website>
68
+ <show_in_store>1</show_in_store>
69
+ <comment><![CDATA[Start FACTFinder suggest import after each export]]></comment>
70
+ </trigger_suggest_import>
71
+ </fields>
72
+ </export>
73
+ <config>
74
+ <fields>
75
+ <proxy translate="label">
76
+ <label>Use Proxy for Suggest</label>
77
+ <frontend_type>select</frontend_type>
78
+ <source_model>adminhtml/system_config_source_yesno</source_model>
79
+ <sort_order>10</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>1</show_in_website>
82
+ <show_in_store>1</show_in_store>
83
+ </proxy>
84
+ </fields>
85
+ </config>
86
+ </groups>
87
+ </factfinder>
88
+ </sections>
89
+ </config>
app/code/community/FACTFinder/Tagcloud/Block/TagCloud.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_TagCloud
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_TagCloud
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Block class
16
+ *
17
+ * Is used instead of the default block
18
+ *
19
+ * @category Mage
20
+ * @package FACTFinder_TagCloud
21
+ * @author Flagbit Magento Team <magento@flagbit.de>
22
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
23
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24
+ * @link http://www.flagbit.de
25
+ */
26
+ class FACTFinder_Tagcloud_Block_TagCloud extends Mage_CatalogSearch_Block_Term
27
+ {
28
+
29
+
30
+ /**
31
+ * @return string
32
+ */
33
+ protected function _toHtml()
34
+ {
35
+ if (!Mage::helper('factfinder')->isEnabled('tagcloud')) {
36
+ return '';
37
+ }
38
+
39
+ // only show on "no result" page
40
+ $searchResultBlock = $this->getLayout()->getBlock('search.result');
41
+ if(!$searchResultBlock || ($searchResultBlock && $searchResultBlock->getResultCount())) {
42
+ return '';
43
+ }
44
+
45
+ return parent::_toHtml();
46
+ }
47
+
48
+
49
+ /**
50
+ * @return FACTFinder_Tagcloud_Block_TagCloud
51
+ */
52
+ protected function _loadTerms()
53
+ {
54
+ $handler = Mage::getModel('factfinder_tagcloud/handler_tagCloud');
55
+ if (empty($this->_terms)) {
56
+ $this->_terms = $handler->getTerms();
57
+
58
+ if (count($this->_terms) == 0) {
59
+ return $this;
60
+ }
61
+
62
+ $this->determineMinMaxPopularity();
63
+ }
64
+
65
+ return $this;
66
+ }
67
+
68
+
69
+ /**
70
+ * Determines minimum and maximum popularity among terms
71
+ *
72
+ * @return void
73
+ */
74
+ protected function determineMinMaxPopularity()
75
+ {
76
+ $this->_maxPopularity = 0;
77
+ $this->_minPopularity = 1;
78
+
79
+ foreach ($this->_terms as $term) {
80
+ if ($term->getPopularity() > $this->_maxPopularity) {
81
+ $this->_maxPopularity = $term->getPopularity();
82
+ }
83
+
84
+ if ($term->getPopularity() < $this->_minPopularity) {
85
+ $this->_minPopularity = $term->getPopularity();
86
+ }
87
+ }
88
+ }
89
+ }
app/code/community/FACTFinder/Tagcloud/Helper/Data.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_TagCloud
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_TagCloud
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_TagCloud
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tagcloud_Helper_Data extends Mage_Core_Helper_Abstract
25
+ {
26
+
27
+ }
app/code/community/FACTFinder/Tagcloud/Model/Facade.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_TagCloud
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_TagCloud
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_TagCloud
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tagcloud_Model_Facade extends FACTFinder_Core_Model_Facade
25
+ {
26
+
27
+
28
+ /**
29
+ * Get tag cloud adapter
30
+ *
31
+ * @param string $channel
32
+ *
33
+ * @return \FACTFinder\Adapter\AbstractAdapter
34
+ */
35
+ public function getTagCloudAdapter($channel = null)
36
+ {
37
+ return $this->_getAdapter("tagCloud", $channel);
38
+ }
39
+
40
+
41
+ /**
42
+ * Configure tag cloud adapter
43
+ *
44
+ * @param array $params
45
+ * @param string $channel
46
+ * @param int $id
47
+ *
48
+ * @return void
49
+ */
50
+ public function configureTagCloudAdapter($params, $channel = null, $id = null)
51
+ {
52
+ $this->_configureAdapter($params, "tagCloud", $channel, $id);
53
+ }
54
+
55
+
56
+ /**
57
+ * Get tag cloud object
58
+ *
59
+ * @param string $channel
60
+ * @param int $id
61
+ *
62
+ * @return Object
63
+ */
64
+ public function getTagCloud($channel = null, $id = null)
65
+ {
66
+ return $this->_getFactFinderObject("tagCloud", "getTagCloud", $channel, $id);
67
+ }
68
+
69
+
70
+ }
app/code/community/FACTFinder/Tagcloud/Model/Handler/TagCloud.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_TagCloud
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_TagCloud
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_TagCloud
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tagcloud_Model_Handler_TagCloud extends FACTFinder_Core_Model_Handler_Abstract
25
+ {
26
+
27
+ /**
28
+ * @var array
29
+ */
30
+ protected $_tagCloud;
31
+
32
+
33
+ /**
34
+ * Get an instance of FACT-Finder facade
35
+ *
36
+ * @return FACTFinder_Tagcloud_Model_Facade
37
+ */
38
+ protected function _getFacade()
39
+ {
40
+ if ($this->_facade === null) {
41
+ $this->_facade = Mage::getSingleton('factfinder_tagcloud/facade');
42
+ }
43
+
44
+ return $this->_facade;
45
+ }
46
+
47
+
48
+ /**
49
+ * Configure adapter
50
+ *
51
+ * @return void
52
+ */
53
+ protected function _configureFacade()
54
+ {
55
+ // Registering the needed tag cloud adapter
56
+ $this->_getFacade()->configureTagCloudAdapter(array());
57
+ }
58
+
59
+
60
+ /**
61
+ * Get terms array
62
+ *
63
+ * @return array
64
+ */
65
+ public function getTerms()
66
+ {
67
+ $tagCloud = $this->_getTagCloud();
68
+
69
+ $terms = array();
70
+ foreach ($tagCloud as $item) {
71
+ $terms[] = new Varien_Object($this->assembleTermArray($item));
72
+ }
73
+
74
+ return $terms;
75
+ }
76
+
77
+
78
+ /**
79
+ * Convert ff item to array
80
+ *
81
+ * @param \FACTFinder\Data\TagQuery $item
82
+ *
83
+ * @return array
84
+ */
85
+ protected function assembleTermArray($item)
86
+ {
87
+ $termArray = array(
88
+ 'name' => $item->getLabel(),
89
+ 'url' => $item->getUrl(),
90
+ 'popularity' => $item->getWeight(),
91
+ 'ratio' => $item->getWeight(),
92
+ );
93
+
94
+ return $termArray;
95
+ }
96
+
97
+
98
+ /**
99
+ * Retrieve tag cloud array
100
+ *
101
+ * @return array
102
+ */
103
+ protected function _getTagCloud()
104
+ {
105
+ if ($this->_tagCloud === null) {
106
+ $this->_tagCloud = $this->_getFacade()->getTagCloud();
107
+ if ($this->_tagCloud === null) {
108
+ Mage::helper('factfinder')->performFallbackRedirect();
109
+ }
110
+ }
111
+
112
+ return $this->_tagCloud;
113
+ }
114
+
115
+
116
+ }
117
+
app/code/community/FACTFinder/Tagcloud/etc/config.xml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_TagCloud
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_TagCloud
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <modules>
17
+ <FACTFinder_Tagcloud>
18
+ <version>4.0.1</version>
19
+ </FACTFinder_Tagcloud>
20
+ </modules>
21
+ <global>
22
+ <models>
23
+ <factfinder_tagcloud>
24
+ <class>FACTFinder_Tagcloud_Model</class>
25
+ </factfinder_tagcloud>
26
+ </models>
27
+ <blocks>
28
+ <factfinder_tagcloud>
29
+ <class>FACTFinder_Tagcloud_Block</class>
30
+ </factfinder_tagcloud>
31
+ </blocks>
32
+ <helpers>
33
+ <factfinder_tagcloud>
34
+ <class>FACTFinder_Tagcloud_Helper</class>
35
+ </factfinder_tagcloud>
36
+ </helpers>
37
+ </global>
38
+ <frontend>
39
+ <layout>
40
+ <updates>
41
+ <factfinder_tagcloud>
42
+ <file>factfinder/tagcloud.xml</file>
43
+ </factfinder_tagcloud>
44
+ </updates>
45
+ </layout>
46
+ </frontend>
47
+ </config>
app/code/community/FACTFinder/Tracking/Block/Init.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Block class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Block_Init extends Mage_Core_Block_Template
25
+ {
26
+
27
+
28
+ /**
29
+ * Get Product Result Collection
30
+ *
31
+ * @return FACTFinder_Core_Model_Resource_Search_Collection
32
+ */
33
+ protected function _getProductResultCollection()
34
+ {
35
+ return Mage::getSingleton('factfinder/catalogSearch_layer')->getProductCollection();
36
+ }
37
+
38
+
39
+ /**
40
+ * Get Product URL to ID Mapping JSON Object
41
+ *
42
+ * @return string
43
+ */
44
+ public function getJsonUrlToIdMappingObject()
45
+ {
46
+ $data = array();
47
+ foreach($this->_getProductResultCollection() as $product){
48
+ $data[$product->getProductUrl()] = $product->getId();
49
+ }
50
+
51
+ return Mage::helper('core')->jsonEncode($data);
52
+ }
53
+
54
+
55
+ /**
56
+ * Get Product and Search Details by ID as JSON Object
57
+ *
58
+ * @return string
59
+ */
60
+ public function getJsonDataObject()
61
+ {
62
+ $searchHelper = Mage::helper('factfinder/search');
63
+ $idFieldName = Mage::helper('factfinder_tracking')->getIdFieldName();
64
+
65
+ $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
66
+ if ($customerId) {
67
+ $customerId = md5('customer_' . $customerId);
68
+ }
69
+
70
+ $dataTemplate = array(
71
+ 'query' => $searchHelper->getQuery()->getQueryText(),
72
+ 'page' => $searchHelper->getCurrentPage(),
73
+ 'sid' => Mage::helper('factfinder_tracking')->getSessionId(),
74
+ 'pageSize' => $searchHelper->getPageLimit(),
75
+ 'origPageSize' => $searchHelper->getDefaultPerPageValue(),
76
+ 'channel' => Mage::getStoreConfig('factfinder/search/channel'),
77
+ 'userId' => $customerId,
78
+ 'event' => 'click'
79
+ );
80
+
81
+ $data = array();
82
+ foreach($this->_getProductResultCollection() as $product){
83
+ $key = $product->getId();
84
+
85
+ $data[$key] = array(
86
+ 'id' => $product->getData($idFieldName),
87
+ 'masterid' => $product->getData($idFieldName),
88
+ 'pos' => $product->getPosition(),
89
+ 'origPos' => $product->getOriginalPosition() ? $product->getOriginalPosition() : $product->getPosition(),
90
+ 'title' => $product->getName(),
91
+ 'simi' => $product->getSimilarity()
92
+ );
93
+
94
+ $data[$key] += $dataTemplate;
95
+ }
96
+
97
+ return Mage::helper('core')->jsonEncode($data);
98
+ }
99
+
100
+
101
+ }
app/code/community/FACTFinder/Tracking/Helper/Data.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Helper class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Helper_Data extends Mage_Core_Helper_Abstract
25
+ {
26
+
27
+ /**
28
+ * Get the correct path where the tracking should be sent
29
+ *
30
+ * @return string
31
+ */
32
+ public function getTrackingUrlPath()
33
+ {
34
+ return 'ff_tracking/proxy/tracking';
35
+ }
36
+
37
+ /**
38
+ * Get session id which was initialy saved at session start
39
+ *
40
+ * @return string
41
+ */
42
+ public function getSessionId()
43
+ {
44
+ return md5(Mage::getSingleton('customer/session')->getData('ff_session_id'));
45
+ }
46
+
47
+
48
+ /**
49
+ * Get id field name for tracking
50
+ *
51
+ * @return bool
52
+ */
53
+ public function getIdFieldName()
54
+ {
55
+ return Mage::getStoreConfig('factfinder/config/tracking_identifier');
56
+ }
57
+
58
+
59
+ }
app/code/community/FACTFinder/Tracking/Model/Facade.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Facade extends FACTFinder_Core_Model_Facade
25
+ {
26
+
27
+
28
+ /**
29
+ * Get instance of tracking adapter
30
+ *
31
+ * @param string $channel
32
+ *
33
+ * @return \FACTFinder\Adapter\AbstractAdapter
34
+ */
35
+ public function getTrackingAdapter($channel = null)
36
+ {
37
+ return $this->_getAdapter("tracking", $channel);
38
+ }
39
+
40
+ }
app/code/community/FACTFinder/Tracking/Model/Handler/Tracking.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Handler_Tracking extends FACTFinder_Core_Model_Handler_Abstract
25
+ {
26
+
27
+ protected $_facadeModel = 'factfinder_tracking/facade';
28
+
29
+
30
+ /**
31
+ * Just a stub
32
+ *
33
+ * @return void
34
+ */
35
+ protected function _configureFacade()
36
+ {
37
+ }
38
+
39
+ /**
40
+ * Track login of a user
41
+ *
42
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
43
+ * @param string $cookieId cookie id (optional)
44
+ * @param string $userid id of user who logged in
45
+ * @return boolean $success
46
+ */
47
+ public function trackLogin(
48
+ $sid = null,
49
+ $cookieId = null,
50
+ $userid = null
51
+ ) {
52
+ return $this->_getFacade()->getTrackingAdapter()->trackLogin(
53
+ $sid,
54
+ $cookieId,
55
+ $userid
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Track a product which was added to the cart.
61
+ *
62
+ * @param string $id id of product
63
+ * @param string $masterId masterId of product if variant
64
+ * @param string $title title of product (optional - is empty by default)
65
+ * @param string $query query which led to the product (only if module Semantic Enhancer is used)
66
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
67
+ * @param string $cookieId cookie id (optional)
68
+ * @param int $count number of items purchased for each product (optional - default 1)
69
+ * @param float $price this is the single unit price (optional)
70
+ * @param string $userid id of user (optional if modul personalisation is not used)
71
+ *
72
+ * @return boolean
73
+ */
74
+ public function trackCart(
75
+ $id,
76
+ $masterId = null,
77
+ $title = '',
78
+ $query = null,
79
+ $sid = null,
80
+ $cookieId = null,
81
+ $count = 1,
82
+ $price = null,
83
+ $userid = null
84
+ ) {
85
+ return $this->_getFacade()->getTrackingAdapter()->trackCart(
86
+ $id,
87
+ $masterId,
88
+ $title,
89
+ $query,
90
+ $sid,
91
+ $cookieId,
92
+ $count,
93
+ $price,
94
+ $userid
95
+ );
96
+ }
97
+
98
+
99
+ /**
100
+ * Track a detail click on a product.
101
+ *
102
+ * @param string $id id of product
103
+ * @param string $query query which led to the product
104
+ * @param int $pos position of product in the search result
105
+ * @param mixed $masterId
106
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
107
+ * @param mixed $cookieId
108
+ * @param int $origPos original product position in search result. this data is delivered by ff (optional)
109
+ * @param int $page page number where the product was clicked (optional - is 1 by default)
110
+ * @param float $simi similarity of the product (optional - is 100.00 by default)
111
+ * @param string $title title of product (optional - is empty by default)
112
+ * @param int $pageSize size of the page where the product was found (optional - is 12 by default)
113
+ * @param int $origPageSize original size of the page before the user could have changed it (optional)
114
+ * @param int $userid
115
+ *
116
+ * @return bool
117
+ */
118
+ public function trackClick(
119
+ $id,
120
+ $query,
121
+ $pos,
122
+ $masterId = null,
123
+ $sid = null,
124
+ $cookieId = null,
125
+ $origPos = -1,
126
+ $page = 1,
127
+ $simi = 100.0,
128
+ $title = '',
129
+ $pageSize = 12,
130
+ $origPageSize = -1,
131
+ $userid = null
132
+ ) {
133
+ return $this->_getFacade()->getTrackingAdapter()->trackClick(
134
+ $id,
135
+ $query,
136
+ $pos,
137
+ $masterId,
138
+ $sid,
139
+ $cookieId,
140
+ $origPos,
141
+ $page,
142
+ $simi,
143
+ $title,
144
+ $pageSize,
145
+ $origPageSize,
146
+ $userid
147
+ );
148
+ }
149
+
150
+
151
+ /**
152
+ *
153
+ * Use this method directly if you want to separate the setup from sending
154
+ * the request. This is particularly useful when using the
155
+ * MultiCurlRequestFactory.
156
+ *
157
+ * @param string $id
158
+ * @param string $masterId
159
+ * @param string $title
160
+ * @param string $query
161
+ * @param int $sid
162
+ * @param string $cookieId
163
+ * @param int $count
164
+ * @param float $price
165
+ * @param int $userid
166
+ *
167
+ * @return mixed
168
+ */
169
+ public function setupCheckoutTracking(
170
+ $id,
171
+ $masterId = null,
172
+ $title = '',
173
+ $query = null,
174
+ $sid = null,
175
+ $cookieId = null,
176
+ $count = 1,
177
+ $price = null,
178
+ $userid = null
179
+ ) {
180
+ return $this->_getFacade()->getTrackingAdapter($id)->setupCheckoutTracking(
181
+ $id,
182
+ $masterId,
183
+ $title,
184
+ $query,
185
+ $sid,
186
+ $cookieId,
187
+ $count,
188
+ $price,
189
+ $userid
190
+ );
191
+ }
192
+
193
+
194
+ /**
195
+ * Send tracking
196
+ *
197
+ * @param mixed $instance
198
+ *
199
+ * @return bool
200
+ */
201
+ public function applyTracking($instance = null)
202
+ {
203
+ return $this->_getFacade()->getTrackingAdapter($instance)->applyTracking();
204
+ }
205
+
206
+
207
+ }
app/code/community/FACTFinder/Tracking/Model/Observer.php ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Observer
25
+ {
26
+
27
+ protected $_facadeModel = 'factfinder_tracking/facade';
28
+
29
+
30
+ /**
31
+ * Add tracking handle to the layout
32
+ *
33
+ * @param Varien_Object $observer
34
+ *
35
+ * @return void
36
+ */
37
+ public function addTrackingHandles($observer)
38
+ {
39
+ if (!Mage::getStoreConfig('factfinder/export/clicktracking')
40
+ || !Mage::helper('factfinder/search')->getIsOnSearchPage()
41
+ || !Mage::helper('factfinder')->isEnabled('tracking')
42
+ ) {
43
+ return;
44
+ }
45
+
46
+ $layout = $observer->getLayout();
47
+ $update = $layout->getUpdate();
48
+ $update->addHandle('factfinder_clicktracking_enabled');
49
+ }
50
+
51
+
52
+ /**
53
+ * Observer method.
54
+ * Sends information to FACT-Finder if item was added to cart.
55
+ *
56
+ * @param Varien_Event_Observer $observer
57
+ *
58
+ * @return void
59
+ */
60
+ public function addToCartTracking($observer)
61
+ {
62
+ if (!Mage::getStoreConfigFlag('factfinder/export/track_carts')
63
+ || !Mage::helper('factfinder')->isEnabled('tracking')
64
+ ) {
65
+ return;
66
+ }
67
+
68
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
69
+ $quoteItem = $observer->getQuoteItem();
70
+
71
+ /** @var Mage_Catalog_Model_Product $product */
72
+ $product = $observer->getProduct();
73
+
74
+ $idFieldName = Mage::helper('factfinder_tracking')->getIdFieldName();
75
+
76
+ $qty = $quoteItem->getQty();
77
+
78
+ $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
79
+ if ($customerId) {
80
+ $customerId = md5('customer_' . $customerId);
81
+ }
82
+
83
+ try {
84
+ /** @var $tracking FACTFinder_Tracking_Model_Handler_Tracking */
85
+ $tracking = Mage::getModel('factfinder_tracking/handler_tracking');
86
+ $tracking->trackCart(
87
+ $quoteItem->getProductId(),
88
+ $product->getData($idFieldName),
89
+ $product->getName(),
90
+ null,
91
+ Mage::helper('factfinder_tracking')->getSessionId(),
92
+ null,
93
+ $qty,
94
+ $product->getFinalPrice($qty),
95
+ $customerId
96
+ );
97
+ } catch (Exception $e) {
98
+ Mage::helper('factfinder/debug')->log($e->getMessage());
99
+ }
100
+ }
101
+
102
+
103
+ /**
104
+ * Tracking of single product click
105
+ *
106
+ * @param \Varien_Event_Observer $observer
107
+ *
108
+ * @internal param $product
109
+ */
110
+ public function sendClickTrackingForRedirectOnSingleResult(Varien_Event_Observer $observer)
111
+ {
112
+ $product = $observer->getProduct();
113
+ $searchHelper = Mage::helper('factfinder/search');
114
+
115
+ if (!Mage::getStoreConfig('factfinder/export/clicktracking')
116
+ || !Mage::helper('factfinder')->isEnabled('tracking')
117
+ ) {
118
+ return;
119
+ }
120
+
121
+ try {
122
+ $idFieldName = Mage::helper('factfinder_tracking')->getIdFieldName();
123
+
124
+ $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
125
+ if ($customerId) {
126
+ $customerId = md5('customer_' . $customerId);
127
+ }
128
+
129
+ /** @var FACTFinder_Tracking_Model_Handler_Tracking $tracking */
130
+ $tracking = Mage::getModel('factfinder_tracking/handler_tracking');
131
+ $tracking->trackClick(
132
+ $product->getData($idFieldName),
133
+ $searchHelper->getQuery()->getQueryText(),
134
+ 1, // pos,
135
+ $product->getData($idFieldName), // master id but there's none on redirect
136
+ Mage::helper('factfinder_tracking')->getSessionId(),
137
+ null,
138
+ 1, // origPos
139
+ 1, // page
140
+ $product->getSimilarity(),
141
+ $product->getName(),
142
+ $searchHelper->getPageLimit(),
143
+ $searchHelper->getDefaultPerPageValue(),
144
+ $customerId
145
+ );
146
+ }
147
+ catch (Exception $e) {
148
+ Mage::helper('factfinder/debug')->log($e->getMessage());
149
+ }
150
+ }
151
+
152
+
153
+ /**
154
+ * Observer method
155
+ * Adds all ordered items to queue that is sent to FACT-Finder by Cronjob.
156
+ *
157
+ * @param Varien_Event_Observer $observer
158
+ *
159
+ * @return void
160
+ */
161
+ public function addOrderDetailsToQueue($observer)
162
+ {
163
+ if (!Mage::getStoreConfigFlag('factfinder/export/track_checkout')
164
+ || !Mage::helper('factfinder')->isEnabled('tracking')
165
+ ) {
166
+ return;
167
+ }
168
+
169
+ $order = $observer->getOrder();
170
+ $customerId = $order->getCustomerId();
171
+ if ($customerId) {
172
+ $customerId = md5('customer_' . $customerId);
173
+ }
174
+
175
+ $searchHelper = Mage::helper('factfinder/search');
176
+ $idFieldName = Mage::helper('factfinder_tracking')->getIdFieldName();
177
+ if ($idFieldName == 'entity_id') {
178
+ $idFieldName = 'product_id'; // sales_order_item does not contain a entity_id
179
+ }
180
+
181
+ foreach ($order->getAllItems() as $item) {
182
+ if ($item->getParentItem() != null) {
183
+ continue;
184
+ }
185
+
186
+ try {
187
+ Mage::getModel('factfinder_tracking/queue')
188
+ ->setProductId($item->getData($idFieldName))
189
+ ->setProductName($item->getName())
190
+ ->setSid(Mage::helper('factfinder_tracking')->getSessionId())
191
+ ->setUserid($customerId)
192
+ ->setPrice($item->getPrice())
193
+ ->setCount($item->getQtyOrdered())
194
+ ->save();
195
+ }
196
+ catch (Exception $e) {
197
+ Mage::logException($e);
198
+ }
199
+ }
200
+ }
201
+
202
+
203
+ /**
204
+ * Cronjob observer method.
205
+ * Processes all orders given in queue and sends them to FACT-Finder.
206
+ *
207
+ * @return void
208
+ */
209
+ public function processOrderQueue()
210
+ {
211
+ if (!Mage::helper('factfinder')->isEnabled('tracking')) {
212
+ return;
213
+ }
214
+
215
+ $queue = Mage::getModel('factfinder_tracking/queue');
216
+
217
+ try {
218
+ $collectionSize = $queue->getCollection()->getSize();
219
+ foreach ($queue->getCollection() as $item) {
220
+ /** @var FACTFinder_Tracking_Model_Handler_Tracking $tracking */
221
+ $tracking = Mage::getModel('factfinder_tracking/handler_tracking');
222
+ $tracking->setupCheckoutTracking(
223
+ $item->getProductId(),
224
+ $item->getProductId(),
225
+ $item->getProductName(),
226
+ null,
227
+ $item->getSid(),
228
+ null,
229
+ $item->getCount(),
230
+ $item->getPrice(),
231
+ $item->getUserid()
232
+ );
233
+
234
+ $item->delete($item);
235
+ }
236
+
237
+ if ($collectionSize > 0) {
238
+ // We use the last adapter instance to start the parallel request
239
+ $tracking->applyTracking($item->getProductId());
240
+ }
241
+ } catch (Exception $e) {
242
+ Mage::logException($e);
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Store initial session id to be able to recognize the user sill after login
248
+ *
249
+ * @param Varien_Event_Observer $observer
250
+ */
251
+ public function storeSessionId(Varien_Event_Observer $observer)
252
+ {
253
+ $customerSession = Mage::getSingleton('customer/session');
254
+ if (!$customerSession->getData('ff_session_id')) {
255
+ $customerSession->setData('ff_session_id', $customerSession->getEncryptedSessionId());
256
+ }
257
+ }
258
+
259
+ public function loginTracking(Varien_Event_Observer $observer)
260
+ {
261
+ if(!Mage::getStoreConfigFlag('factfinder/config/personalization')) {
262
+ return;
263
+ }
264
+
265
+ $customer = $observer->getCustomer();
266
+ if($customer->getId()) {
267
+
268
+ $customerId = md5('customer_' . $customer->getId());
269
+
270
+ /** @var $tracking Flagbit_FactFinder_Model_Handler_Tracking */
271
+ $tracking = Mage::getModel('factfinder_tracking/handler_tracking');
272
+ $tracking->trackLogin(
273
+ Mage::helper('factfinder_tracking')->getSessionId(),
274
+ null,
275
+ $customerId
276
+ );
277
+ }
278
+ }
279
+ }
app/code/community/FACTFinder/Tracking/Model/Processor.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ require_once BP . DS . 'lib' . DS . 'FACTFinder' . DS . 'Loader.php';
15
+
16
+ /**
17
+ * Model class
18
+ *
19
+ * Request Processor for click tracking handling
20
+ *
21
+ * @category Mage
22
+ * @package FACTFinder_Tracking
23
+ * @author Flagbit Magento Team <magento@flagbit.de>
24
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ * @link http://www.flagbit.de
27
+ */
28
+ class FACTFinder_Tracking_Model_Processor
29
+ {
30
+
31
+ /**
32
+ * FactFinder Facade
33
+ *
34
+ * @var FACTFinder_Core_Model_Facade
35
+ */
36
+ protected $_facade;
37
+
38
+
39
+ /**
40
+ * @var array with loaded config values
41
+ */
42
+ protected $_config;
43
+
44
+ /**
45
+ * Class constructor
46
+ */
47
+ public function __construct()
48
+ {
49
+ $this->_initFFAutoloader();
50
+ }
51
+
52
+
53
+ /**
54
+ * Init fact-finder lib autoloader
55
+ *
56
+ * @return void
57
+ */
58
+ protected function _initFFAutoloader()
59
+ {
60
+ $autoloaderClass = new FACTFinder_Core_Model_Autoloader();
61
+ $autoloaderClass->addAutoloader(new Varien_Event_Observer());
62
+ }
63
+
64
+
65
+ /**
66
+ * Get Fact-Finder Facade
67
+ * we do it manually, because we do not have the full magento context
68
+ *
69
+ * @param mixed $config
70
+ *
71
+ * @return FACTFinder_Core_Model_Facade
72
+ */
73
+ protected function _getFacade($config = null)
74
+ {
75
+ if ($this->_facade === null) {
76
+ $logger = new FACTFinder_Core_Helper_Debug();
77
+ $this->_facade = new FACTFinder_Tracking_Model_Facade($logger, $config);
78
+ }
79
+
80
+ return $this->_facade;
81
+ }
82
+
83
+ /**
84
+ * Bypass app cache.
85
+ *
86
+ * @param string $content
87
+ *
88
+ * @return false
89
+ */
90
+ public function extractContent($content)
91
+ {
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * handle Requests
97
+ *
98
+ * @param string $request
99
+ *
100
+ * @return string
101
+ */
102
+ public function handleRequest($request)
103
+ {
104
+ return $this->_getFacade()->getTrackingAdapter()->doTrackingFromRequest();
105
+ }
106
+ }
app/code/community/FACTFinder/Tracking/Model/Queue.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Queue extends Mage_Core_Model_Abstract
25
+ {
26
+
27
+
28
+ /**
29
+ * Initialization method
30
+ *
31
+ * @return void
32
+ */
33
+ public function _construct()
34
+ {
35
+ $this->_init('factfinder_tracking/queue');
36
+ }
37
+
38
+
39
+ }
app/code/community/FACTFinder/Tracking/Model/Resource/Queue.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Resource_Queue extends Mage_Core_Model_Resource_Db_Abstract
25
+ {
26
+
27
+
28
+ /**
29
+ * Initialization here
30
+ *
31
+ * @return void
32
+ */
33
+ protected function _construct()
34
+ {
35
+ $this->_init('factfinder_tracking/queue', 'id');
36
+ }
37
+
38
+
39
+ }
app/code/community/FACTFinder/Tracking/Model/Resource/Queue/Collection.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Model class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_Model_Resource_Queue_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
25
+ {
26
+
27
+
28
+ /**
29
+ * Initialization here
30
+ *
31
+ * @return void
32
+ */
33
+ protected function _construct()
34
+ {
35
+ $this->_init('factfinder_tracking/queue')
36
+ ->setOrder('id', 'DESC');
37
+ }
38
+
39
+
40
+ }
app/code/community/FACTFinder/Tracking/controllers/ProxyController.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+
14
+ /**
15
+ * Controller class
16
+ *
17
+ * @category Mage
18
+ * @package FACTFinder_Tracking
19
+ * @author Flagbit Magento Team <magento@flagbit.de>
20
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
21
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
22
+ * @link http://www.flagbit.de
23
+ */
24
+ class FACTFinder_Tracking_ProxyController extends Mage_Core_Controller_Front_Action
25
+ {
26
+
27
+
28
+ /**
29
+ * tracking Action
30
+ */
31
+ public function trackingAction()
32
+ {
33
+ $this->getResponse()->setBody(
34
+ Mage::getModel('factfinder_tracking/processor')->handleRequest($this->getFullActionName())
35
+ );
36
+ }
37
+
38
+
39
+ }
app/code/community/FACTFinder/Tracking/etc/config.xml ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Tracking
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Tracking
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <modules>
17
+ <FACTFinder_Tracking>
18
+ <version>4.0.1</version>
19
+ </FACTFinder_Tracking>
20
+ </modules>
21
+ <global>
22
+ <blocks>
23
+ <factfinder_tracking>
24
+ <class>FACTFinder_Tracking_Block</class>
25
+ </factfinder_tracking>
26
+ </blocks>
27
+ <helpers>
28
+ <factfinder_tracking>
29
+ <class>FACTFinder_Tracking_Helper</class>
30
+ </factfinder_tracking>
31
+ </helpers>
32
+ <models>
33
+ <factfinder_tracking>
34
+ <class>FACTFinder_Tracking_Model</class>
35
+ <resourceModel>factfinder_tracking_resource</resourceModel>
36
+ </factfinder_tracking>
37
+ <factfinder_tracking_resource>
38
+ <class>FACTFinder_Tracking_Model_Resource</class>
39
+ <entities>
40
+ <queue>
41
+ <table>factfinder_tracking_queue</table>
42
+ </queue>
43
+ </entities>
44
+ </factfinder_tracking_resource>
45
+ </models>
46
+ <resources>
47
+ <factfinder_tracking_setup>
48
+ <setup>
49
+ <module>FACTFinder_Tracking</module>
50
+ </setup>
51
+ <connection>
52
+ <use>core_setup</use>
53
+ </connection>
54
+ </factfinder_tracking_setup>
55
+ </resources>
56
+ </global>
57
+ <frontend>
58
+ <routers>
59
+ <factfinder_tracking>
60
+ <use>standard</use>
61
+ <args>
62
+ <module>FACTFinder_Tracking</module>
63
+ <frontName>ff_tracking</frontName>
64
+ </args>
65
+ </factfinder_tracking>
66
+ </routers>
67
+ <layout>
68
+ <updates>
69
+ <factfinder_tracking>
70
+ <file>factfinder/tracking.xml</file>
71
+ </factfinder_tracking>
72
+ </updates>
73
+ </layout>
74
+ <events>
75
+ <controller_action_layout_load_before>
76
+ <observers>
77
+ <factfinder_tracking_addActivationLayoutHandles>
78
+ <class>factfinder_tracking/observer</class>
79
+ <method>addTrackingHandles</method>
80
+ </factfinder_tracking_addActivationLayoutHandles>
81
+ </observers>
82
+ </controller_action_layout_load_before>
83
+ <checkout_cart_product_add_after>
84
+ <observers>
85
+ <factfinder_tracking_cartProductAddAfter>
86
+ <class>factfinder_tracking/observer</class>
87
+ <method>addToCartTracking</method>
88
+ </factfinder_tracking_cartProductAddAfter>
89
+ </observers>
90
+ </checkout_cart_product_add_after>
91
+ <sales_model_service_quote_submit_after>
92
+ <observers>
93
+ <factfinder_tracking_salesModelServiceQuoteSubmitAfter>
94
+ <class>factfinder_tracking/observer</class>
95
+ <method>addOrderDetailsToQueue</method>
96
+ </factfinder_tracking_salesModelServiceQuoteSubmitAfter>
97
+ </observers>
98
+ </sales_model_service_quote_submit_after>
99
+ <factfinder_redirect_on_single_result_before>
100
+ <observers>
101
+ <factfinder_tracking_on_single_result_redirect>
102
+ <class>factfinder_tracking/observer</class>
103
+ <method>sendClickTrackingForRedirectOnSingleResult</method>
104
+ </factfinder_tracking_on_single_result_redirect>
105
+ </observers>
106
+ </factfinder_redirect_on_single_result_before>
107
+ <controller_action_predispatch>
108
+ <observers>
109
+ <factfinder_tracking_store_session_id>
110
+ <type>singleton</type>
111
+ <class>factfinder_tracking/observer</class>
112
+ <method>storeSessionId</method>
113
+ </factfinder_tracking_store_session_id>
114
+ </observers>
115
+ </controller_action_predispatch>
116
+ <customer_login>
117
+ <observers>
118
+ <factfinder_tracking_customer_login>
119
+ <type>singleton</type>
120
+ <class>factfinder_tracking/observer</class>
121
+ <method>loginTracking</method>
122
+ </factfinder_tracking_customer_login>
123
+ </observers>
124
+ </customer_login>
125
+ </events>
126
+ </frontend>
127
+ <default>
128
+ <factfinder>
129
+ <export>
130
+ <clicktracking>1</clicktracking>
131
+ <track_carts>1</track_carts>
132
+ <track_checkout>1</track_checkout>
133
+ </export>
134
+ <config>
135
+ <tracking_identifier>entity_id</tracking_identifier>
136
+ </config>
137
+ </factfinder>
138
+ </default>
139
+ <crontab>
140
+ <jobs>
141
+ <factfinder_tracking_queue_processing>
142
+ <schedule>
143
+ <cron_expr>*/5 * * * *</cron_expr>
144
+ </schedule>
145
+ <run>
146
+ <model>factfinder_tracking/observer::processOrderQueue</model>
147
+ </run>
148
+ </factfinder_tracking_queue_processing>
149
+ </jobs>
150
+ </crontab>
151
+ </config>
app/code/community/FACTFinder/Tracking/etc/system.xml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Tracking
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Tracking
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <config>
16
+ <sections>
17
+ <factfinder>
18
+ <groups>
19
+ <export>
20
+ <fields>
21
+ <clicktracking translate="label">
22
+ <label>Track product-clicks</label>
23
+ <frontend_type>select</frontend_type>
24
+ <source_model>adminhtml/system_config_source_yesno</source_model>
25
+ <sort_order>20</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>1</show_in_website>
28
+ <show_in_store>1</show_in_store>
29
+ </clicktracking>
30
+ <track_carts translate="label">
31
+ <label>Track "Add to cart" events</label>
32
+ <frontend_type>select</frontend_type>
33
+ <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>30</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ <show_in_website>1</show_in_website>
37
+ <show_in_store>1</show_in_store>
38
+ </track_carts>
39
+ <track_checkout translate="label">
40
+ <label>Track checkout</label>
41
+ <frontend_type>select</frontend_type>
42
+ <source_model>adminhtml/system_config_source_yesno</source_model>
43
+ <sort_order>40</sort_order>
44
+ <show_in_default>1</show_in_default>
45
+ <show_in_website>1</show_in_website>
46
+ <show_in_store>1</show_in_store>
47
+ </track_checkout>
48
+ </fields>
49
+ </export>
50
+ <config>
51
+ <fields>
52
+ <tracking_identifier translate="label">
53
+ <label>Tracking Product Identifier</label>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>factfinder/system_config_source_identifier</source_model>
56
+ <sort_order>12</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <show_in_website>1</show_in_website>
59
+ <show_in_store>1</show_in_store>
60
+ </tracking_identifier>
61
+ </fields>
62
+ </config>
63
+ </groups>
64
+ </factfinder>
65
+ </sections>
66
+ </config>
app/code/community/FACTFinder/Tracking/sql/factfinder_tracking_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+ /**
14
+ * Install script
15
+ *
16
+ * Install script for Tracking queue. Orders are sent to FACT-Finder asynchronously by cronjobs.
17
+ */
18
+
19
+ $installer = $this;
20
+ $installer->startSetup();
21
+
22
+ $table = $installer->getConnection()
23
+ ->newTable($installer->getTable('factfinder_tracking/queue'))
24
+ ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
25
+ 'identity' => true,
26
+ 'unsigned' => true,
27
+ 'nullable' => false,
28
+ 'primary' => true,
29
+ ), 'ID')
30
+ ->addColumn('product_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
31
+ 'unsigned' => true,
32
+ 'nullable' => false,
33
+ 'default' => '0',
34
+ ), 'Product ID')
35
+ ->addColumn('product_name', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array(), 'Product Name')
36
+ ->addColumn('sid', Varien_Db_Ddl_Table::TYPE_TEXT, 32, array(), 'Session ID')
37
+ ->addColumn('userid', Varien_Db_Ddl_Table::TYPE_TEXT, 32, array(), 'User ID')
38
+ ->addColumn('price', Varien_Db_Ddl_Table::TYPE_DECIMAL, '12,4', array(
39
+ 'nullable' => false,
40
+ 'default' => '0.0000',
41
+ ), 'Price')
42
+ ->addColumn('count', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
43
+ 'nullable' => false,
44
+ 'default' => '0',
45
+ ), 'Count')
46
+ ->setComment('FACTFinder Tracking Queue');
47
+ $installer->getConnection()->createTable($table);
48
+
49
+ $installer->endSetup();
app/code/community/Flagbit/FactFinder/Block/Adminhtml/Cockpit.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Black class
12
- *
13
- * This Block class provides the FACT-Finder Business User Cockpit Authentication URL
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_Adminhtml_Cockpit extends Mage_Adminhtml_Block_Template {
22
-
23
- /**
24
- * get FACT-Finder Business User Cockpit Authentication URL
25
- *
26
- * @return string
27
- */
28
- public function getManagementUrl()
29
- {
30
- return Mage::getSingleton('factfinder/facade')->getManagementUrl();
31
- }
32
-
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Adminhtml/Exportlink.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- /**
3
- * Magento
4
- *
5
- * NOTICE OF LICENSE
6
- *
7
- * This source file is subject to the Open Software License (OSL 3.0)
8
- * that is bundled with this package in the file LICENSE.txt.
9
- * It is also available through the world-wide-web at this URL:
10
- * http://opensource.org/licenses/osl-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 Mage
22
- * @package Mage_CatalogInventory
23
- * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
- */
26
-
27
- /**
28
- * Adminhtml export link
29
- *
30
- * @category Mage
31
- * @package Mage_CatalogInventory
32
- * @author Magento Core Team <core@magentocommerce.com>
33
- */
34
- class Flagbit_FactFinder_Block_Adminhtml_Exportlink extends Mage_Adminhtml_Block_System_Config_Form_Field
35
- {
36
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
37
- {
38
- $this->setElement($element);
39
- $shopdomain = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
40
- $activeStore = '';
41
- $store = $this->getRequest()->getParam('store');
42
- if(Mage::getStoreConfig('web/url/use_store'))
43
- {
44
- if ($store)
45
- {
46
- $activeStore = $store.'/';
47
- }
48
- else
49
- {
50
- $websites = Mage::app()->getWebsites();
51
- $activeStore = $websites[1]->getDefaultStore()->getCode().'/';
52
- }
53
- }
54
-
55
- $password = Mage::getStoreConfig('factfinder/search/auth_password', $store);
56
-
57
- if ($store) $storeParam = '&store='.(int)Mage::getConfig()->getNode('stores/' . $store . '/system/store/id');
58
- else $storeParam = '';
59
- $linktext = Mage::helper('factfinder')->__('Download export');
60
-
61
- $html = '<a href="'.$shopdomain.$activeStore.'factfinder/export/product?key='.md5($password).$storeParam.'" target="_blank">'.$linktext.'</a>';
62
- return $html;
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Adminhtml/Form/Field/Attribute.php DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
-
3
- class Flagbit_FactFinder_Block_Adminhtml_Form_Field_Attribute extends Mage_Core_Block_Html_Select
4
- {
5
- /**
6
- * Storeviews cache
7
- *
8
- * @var array
9
- */
10
- private $_attributes;
11
-
12
- /**
13
- * Retrieve allowed Storeviews
14
- *
15
- * @param int $storeId return name by storeview id
16
- * @return array|string
17
- */
18
- protected function _getAttributes($storeId = null)
19
- {
20
- if (is_null($this->_attributes)) {
21
- $this->_attributes = array();
22
- $collection = Mage::getModel('eav/entity_attribute')->getCollection();
23
- $collection->setEntityTypeFilter(Mage::getSingleton('eav/config')->getEntityType('catalog_product'));
24
- foreach ($collection as $item) {
25
- /* @var $item Mage_Core_Model_Store */
26
- $this->_attributes[$item->getAttributeCode()] = $item->getFrontendLabel().' ('.$item->getAttributeCode().')';
27
- }
28
- }
29
- if (!is_null($storeId)) {
30
- return isset($this->_attributes[$storeId]) ? $this->_attributes[$storeId] : null;
31
- }
32
- return $this->_attributes;
33
- }
34
-
35
- public function setInputName($value)
36
- {
37
- return $this->setName($value);
38
- }
39
-
40
- /**
41
- * Render block HTML
42
- *
43
- * @return string
44
- */
45
- public function _toHtml()
46
- {
47
- if (!$this->getOptions()) {
48
- foreach ($this->_getAttributes() as $id => $label) {
49
- $this->addOption($id, addslashes($label));
50
- }
51
- }
52
- return parent::_toHtml();
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Adminhtml/Form/Field/Attributes.php DELETED
@@ -1,85 +0,0 @@
1
- <?php
2
- /**
3
- * Magento
4
- *
5
- * NOTICE OF LICENSE
6
- *
7
- * This source file is subject to the Open Software License (OSL 3.0)
8
- * that is bundled with this package in the file LICENSE.txt.
9
- * It is also available through the world-wide-web at this URL:
10
- * http://opensource.org/licenses/osl-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 Mage
22
- * @package Mage_CatalogInventory
23
- * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
- */
26
-
27
- /**
28
- * Adminhtml catalog inventory "Minimum Qty Allowed in Shopping Cart" field
29
- *
30
- * @category Mage
31
- * @package Mage_CatalogInventory
32
- * @author Magento Core Team <core@magentocommerce.com>
33
- */
34
- class Flagbit_FactFinder_Block_Adminhtml_Form_Field_Attributes extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
35
- {
36
- /**
37
- * @var Flagbit_ContentFromUrl_Block_Adminhtml_Form_Field_Storeview
38
- */
39
- protected $_attributeRenderer;
40
-
41
- /**
42
- * Retrieve group column renderer
43
- *
44
- * @return Flagbit_ContentFromUrl_Block_Adminhtml_Form_Field_Storeview
45
- */
46
- protected function _getAttributeRenderer()
47
- {
48
- if (!$this->_attributeRenderer) {
49
- $this->_attributeRenderer = $this->getLayout()->createBlock(
50
- 'factfinder/adminhtml_form_field_attribute', '',
51
- array('is_render_to_js_template' => true)
52
- );
53
- $this->_attributeRenderer->setClass('attribute_select');
54
- $this->_attributeRenderer->setExtraParams('style="width:200px"');
55
- }
56
- return $this->_attributeRenderer;
57
- }
58
-
59
- /**
60
- * Prepare to render
61
- */
62
- protected function _prepareToRender()
63
- {
64
- $this->addColumn('attribute', array(
65
- 'label' => Mage::helper('factfinder')->__('Attribute'),
66
- 'renderer' => $this->_getAttributeRenderer(),
67
- ));
68
-
69
- $this->_addAfter = false;
70
- $this->_addButtonLabel = Mage::helper('factfinder')->__('Add Attribute');
71
- }
72
-
73
- /**
74
- * Prepare existing row data object
75
- *
76
- * @param Varien_Object
77
- */
78
- protected function _prepareArrayRow(Varien_Object $row)
79
- {
80
- $row->setData(
81
- 'option_extra_attr_' . $this->_getAttributeRenderer()->calcOptionHash($row->getData('attribute')),
82
- 'selected="selected"'
83
- );
84
- }
85
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Advisory.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- class Flagbit_FactFinder_Block_Campaign_Advisory extends Mage_Core_Block_Template
4
- {
5
- protected $_searchHandler;
6
-
7
- protected function _prepareLayout()
8
- {
9
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
10
- $this->_searchHandler = Mage::getSingleton('factfinder/handler_search');
11
- }
12
- }
13
-
14
- /**
15
- * get Campaign Text
16
- *
17
- * @return string
18
- */
19
- public function getActiveQuestions()
20
- {
21
- $questions = array();
22
-
23
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
24
- $_campaigns = $this->_searchHandler->getCampaigns();
25
- if($_campaigns && $_campaigns->hasActiveQuestions()){
26
- $questions = $_campaigns->getActiveQuestions();
27
- }
28
- }
29
-
30
- return $questions;
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Cart/Advisory.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Provides advisory hints to the product view page
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2012 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Mike Becker <mike.becker@flagbit.de>
17
- * @version $Id$
18
- */
19
- class Flagbit_FactFinder_Block_Campaign_Cart_Advisory extends Mage_Core_Block_Template
20
- {
21
- protected $_product;
22
- protected $_productCampaignHandler;
23
-
24
- protected function _prepareLayout()
25
- {
26
- $this->_product = Mage::getModel('catalog/product')->load(Mage::getSingleton('checkout/session')->getLastAddedProductId());
27
-
28
- if($this->canCampaignBeDisplayed()){
29
- $productIds = array(
30
- $this->_product->getData(Mage::helper('factfinder/search')->getIdFieldName())
31
- );
32
-
33
- $this->_productCampaignHandler = Mage::getSingleton('factfinder/handler_shoppingCartCampaign', array($productIds, true));
34
- }
35
- return parent::_prepareLayout();
36
- }
37
-
38
- /**
39
- * get campaign questions and answers
40
- *
41
- * @return array $questions
42
- */
43
- public function getActiveQuestions()
44
- {
45
- Mage::getSingleton('core/session', array('name'=>'frontend'));
46
-
47
- $questions = array();
48
-
49
- if ($this->canCampaignBeDisplayed()) {
50
- $questions = $this->_productCampaignHandler->getActiveAdvisorQuestions();
51
- }
52
-
53
- return $questions;
54
- }
55
-
56
- protected function canCampaignBeDisplayed()
57
- {
58
- return
59
- Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign') &&
60
- Mage::getSingleton('checkout/session')->getLastAddedProductId() &&
61
- $this->_product->getData(Mage::helper('factfinder/search')->getIdFieldName());
62
- }
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Cart/Feedback.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Provides advisory hints to the product view page
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2012 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Mike Becker <mike.becker@flagbit.de>
17
- * @version $Id$
18
- */
19
- class Flagbit_FactFinder_Block_Campaign_Cart_Feedback extends Mage_Core_Block_Template
20
- {
21
- protected $_product;
22
- protected $_productCampaignHandler;
23
-
24
- protected function _prepareLayout()
25
- {
26
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
27
- $this->_product = Mage::getModel('catalog/product')->load(Mage::getSingleton('checkout/session')->getLastAddedProductId());
28
-
29
- $productIds = array(
30
- $this->_product->getData(Mage::helper('factfinder/search')->getIdFieldName())
31
- );
32
-
33
- $this->_productCampaignHandler = Mage::getSingleton('factfinder/handler_shoppingCartCampaign', array($productIds, true));
34
- }
35
- return parent::_prepareLayout();
36
- }
37
-
38
- /**
39
- * get campaign questions and answers
40
- *
41
- * @return array $feedback
42
- */
43
- public function getActiveFeedback()
44
- {
45
- Mage::getSingleton('core/session', array('name'=>'frontend'));
46
-
47
- // only display campaign if they are activated and right after a new product was added to cart
48
- if (!Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign') || !Mage::getSingleton('checkout/session')->getLastAddedProductId()) {
49
- return array();
50
- }
51
-
52
- $feedback = array();
53
-
54
- if (!$this->_product->getData(Mage::helper('factfinder/search')->getIdFieldName())) {
55
- return array();
56
- }
57
-
58
- $_campaigns = $this->_productCampaignHandler->getCampaigns();
59
-
60
- if($_campaigns && $_campaigns->hasFeedback()){
61
- $feedback = $_campaigns;
62
- }
63
-
64
- return $feedback;
65
-
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Feedback.php DELETED
@@ -1,71 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * This class is used to disable Magento´s default Price and Category Filter Output
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id: Scic.php 645 2011-03-17 14:54:20Z weller $
20
- */
21
- class Flagbit_FactFinder_Block_Campaign_Feedback extends Mage_Core_Block_Template
22
- {
23
- /**
24
- * Pushed Products Collection
25
- *
26
- * @var Flagbit_FactFinder_Model_Mysql4_Campaign_Pushedproducts_Collection
27
- */
28
- protected $_pushedProductsCollection = null;
29
-
30
- protected $_searchHandler;
31
-
32
- protected function _prepareLayout()
33
- {
34
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
35
- $this->_searchHandler = Mage::getSingleton('factfinder/handler_search');
36
- }
37
- }
38
-
39
- /**
40
- * get Campaign Text
41
- *
42
- * @return string
43
- */
44
- public function getText()
45
- {
46
- $text = '';
47
-
48
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
49
- $_campaigns = $this->_searchHandler->getCampaigns();
50
- if($_campaigns && $_campaigns->hasFeedback() && $this->getTextNumber()){
51
- $text = $_campaigns->getFeedback($this->getTextNumber() - 1);
52
- }
53
- }
54
-
55
- return $text;
56
- }
57
-
58
- /**
59
- * Pushed Products Collection
60
- *
61
- * @return Flagbit_FactFinder_Model_Mysql4_Campaign_Pushedproducts_Collection
62
- */
63
- public function getPushedProductsCollection()
64
- {
65
- if($this->_pushedProductsCollection === null){
66
- $this->_pushedProductsCollection = Mage::getResourceModel('factfinder/campaign_pushedproducts_collection');
67
- }
68
-
69
- return $this->_pushedProductsCollection;
70
- }
71
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Product/Advisory.php DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Provides advisory hints to the product view page
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2012 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Mike Becker <mike.becker@flagbit.de>
17
- * @version $Id$
18
- */
19
- class Flagbit_FactFinder_Block_Campaign_Product_Advisory extends Mage_Core_Block_Template
20
- {
21
- protected $_productCampaignHandler;
22
-
23
- protected function _prepareLayout()
24
- {
25
- $productIds = array(
26
- Mage::registry('current_product')->getData(Mage::helper('factfinder/search')->getIdFieldName())
27
- );
28
- $this->_productCampaignHandler = Mage::getSingleton('factfinder/handler_productDetailCampaign', $productIds);
29
- return parent::_prepareLayout();
30
- }
31
-
32
- /**
33
- * get campaign questions and answers
34
- *
35
- * @return array $questions
36
- */
37
- public function getActiveQuestions()
38
- {
39
- $questions = array();
40
-
41
- if ($this->canCampaignBeDisplay()) {
42
- $questions = $this->_productCampaignHandler->getActiveAdvisorQuestions();
43
- }
44
-
45
- return $questions;
46
- }
47
-
48
- protected function canCampaignBeDisplay()
49
- {
50
- return
51
- Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign') &&
52
- Mage::registry('current_product');
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Campaign/Product/Feedback.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Provides advisory hints to the product view page
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2012 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Mike Becker <mike.becker@flagbit.de>
17
- * @version $Id$
18
- */
19
- class Flagbit_FactFinder_Block_Campaign_Product_Feedback extends Mage_Core_Block_Template
20
- {
21
- protected $_productCampaignHandler;
22
-
23
- protected function _prepareLayout()
24
- {
25
- $productIds = array(
26
- Mage::registry('current_product')->getData(Mage::helper('factfinder/search')->getIdFieldName())
27
- );
28
- $this->_productCampaignHandler = Mage::getSingleton('factfinder/handler_productDetailCampaign', $productIds);
29
- return parent::_prepareLayout();
30
- }
31
-
32
- /**
33
- * get campaign feedback
34
- *
35
- * @return array $feedback
36
- */
37
- public function getActiveFeedback()
38
- {
39
- $feedback = array();
40
-
41
- if (Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign') && Mage::registry('current_product')) {
42
- $_campaigns = $this->_productCampaignHandler->getCampaigns();
43
-
44
- if($_campaigns && $_campaigns->hasFeedback()){
45
- $feedback = $_campaigns;
46
- }
47
- }
48
-
49
- return $feedback;
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Cart/Crosssell.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Overwritten block.
12
- *
13
- * Replaces the crosssell block within cart view. Gets data from FACT-Finder instead of product link collection.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Block_Cart_Crosssell extends Mage_Checkout_Block_Cart_Crosssell
22
- {
23
- protected $_recommendationsHandler;
24
-
25
- protected function _prepareLayout()
26
- {
27
- if(Mage::getStoreConfigFlag('factfinder/activation/crosssell')){
28
- $productIds = $this->_getCartProductIds();
29
- $this->_recommendationsHandler = Mage::getSingleton('factfinder/handler_recommendations', $productIds);
30
- }
31
- return parent::_prepareLayout();
32
- }
33
-
34
- /**
35
- * Overwritten function. Gets information from FACT-Finder Collection instead of product link collection.
36
- */
37
- public function getItems()
38
- {
39
- if (!Mage::getStoreConfigFlag('factfinder/activation/crosssell')) {
40
- return parent::getItems();
41
- }
42
-
43
- $items = $this->getData('items');
44
- if (is_null($items)) {
45
- $items = array();
46
- $ninProductIds = $this->_getCartProductIds();
47
- if ($ninProductIds) {
48
- $collection = $this->_getCollection()
49
- ->setRecommendations($this->_recommendationsHandler->getRecommendations());
50
- if (!empty($ninProductIds)) {
51
- // Before FF 6.7 only one product id will be considered.
52
- // In that case (only) it could happen that another product in the cart is among the
53
- // recommendations.
54
- // TODO: This filter does not seem to work.
55
- $collection->addExcludeProductFilter($ninProductIds);
56
- }
57
-
58
- foreach ($collection as $item) {
59
- $items[] = $item;
60
- }
61
- }
62
-
63
- $this->setData('items', $items);
64
- }
65
- return $items;
66
- }
67
-
68
- /**
69
- * Get crosssell products collection. Get it from product recommendation collection for communication with FACT-Finder.
70
- *
71
- * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collection
72
- */
73
- protected function _getCollection()
74
- {
75
- if (!Mage::getStoreConfigFlag('factfinder/activation/crosssell')) {
76
- return parent::_getCollection();
77
- }
78
-
79
- $collection = Mage::getResourceModel('factfinder/product_recommendation_collection')
80
- ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
81
- ->setStoreId(Mage::app()->getStore()->getId())
82
- ->addStoreFilter()
83
- ->setPageSize($this->_maxItemCount);
84
- $this->_addProductAttributesAndPrices($collection);
85
-
86
- Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($collection);
87
- Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
88
- Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
89
-
90
- return $collection;
91
- }
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Filter/Slider.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * Add Slider Javascript to HTML Head
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_Filter_Slider extends Mage_Core_Block_Abstract {
22
-
23
- /**
24
- * get Slider Javascript
25
- *
26
- * @return string
27
- */
28
- protected function _toHtml()
29
- {
30
- if(Mage::helper('factfinder/search')->getIsEnabled()){
31
- return '<script type="text/javascript" language="javascript" src="http://static.express.fact-finder.com/onetouchslider-1.0/de.factfinder.asn.slider.OneTouchSlider.nocache.js"></script>'."\n".
32
- '<script type="text/javascript" language="javascript"> oneTouchSliderOnLoad = function(){ document.fire("ffslider:init");}</script>'."\n";
33
-
34
- }
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Layer.php DELETED
@@ -1,154 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * This class is used to disable Magento´s default Price and Category Filter Output
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_Layer extends Flagbit_FactFinder_Block_Layer_Abstract
22
- {
23
- protected $_searchHandler;
24
-
25
- protected $_usesAsn = false;
26
-
27
- /**
28
- * Prepare child blocks
29
- *
30
- * @return Mage_Catalog_Block_Layer_View
31
- */
32
- protected function _prepareLayout()
33
- {
34
- if(!Mage::helper('factfinder/search')->getIsEnabled()){
35
- return parent::_prepareLayout();
36
- }
37
-
38
- $this->_searchHandler = Mage::getSingleton('factfinder/handler_search');
39
- $this->_usesAsn = Mage::helper('factfinder/search')->getIsEnabled(false, 'asn');
40
-
41
- // Make this block globally known so that initializeAfterSearchNavigation can be called on this instance
42
- // when the controller_action_layout_generate_blocks_after event is fired
43
- Mage::register(Flagbit_FactFinder_Model_Observer::_asnBlockRegistryKey, $this, true);
44
-
45
- // Same for handling campaign redirects
46
- Mage::register(Flagbit_FactFinder_Model_Observer::_campaignRedirectRegistryKey, $this, true);
47
-
48
- return Mage_Core_Block_Template::_prepareLayout();
49
- }
50
-
51
- public function handleCampaignRedirect()
52
- {
53
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
54
- // handle redirects
55
- $redirect = $this->_searchHandler->getRedirect();
56
- if($redirect){
57
- $response = Mage::app()->getResponse();
58
- $response->setRedirect($redirect);
59
- $response->sendResponse();
60
- exit;
61
- }
62
- }
63
- }
64
-
65
- public function initializeAfterSearchNavigation()
66
- {
67
- if(!$this->_usesAsn)
68
- return;
69
-
70
- // set default sort Order
71
- if(Mage::getSingleton('catalog/session')->getSortOrder()){
72
- Mage::getSingleton('catalog/session')->setSortOrder('relevance');
73
- }
74
-
75
- $stateBlock = $this->getLayout()->createBlock('catalog/layer_state')
76
- ->setLayer($this->getLayer());
77
-
78
- $this->setChild('layer_state', $stateBlock);
79
-
80
- $filterableAttributes = $this->_getFilterableAttributes();
81
- foreach ($filterableAttributes as $attribute) {
82
- $filterBlockName = $this->_getAttributeFilterBlockName();
83
-
84
- $filterBlock = $this->getLayout()->createBlock($filterBlockName)
85
- ->setLayer($this->getLayer())
86
- ->setAttributeModel($attribute)
87
- ->init();
88
-
89
- switch($attribute->getType()){
90
-
91
- case 'slider':
92
- if(!($this->getLayout()->getBlock('ffslider') instanceof Flagbit_FactFinder_Block_Filter_Slider)){
93
- $this->getLayout()->getBlock('head')->setChild('ffslider', $this->getLayout()->createBlock('factfinder/filter_slider'));
94
- }
95
- $filterBlock->setTemplate('factfinder/filter/slider.phtml');
96
- $filterBlock->setData((current($attribute->getItems())));
97
- $filterBlock->setUnit($attribute->getUnit());
98
- break;
99
- }
100
-
101
- $this->setChild($attribute->getAttributeCode().'_filter', $filterBlock);
102
- }
103
-
104
- $this->getLayer()->apply();
105
- }
106
-
107
- /**
108
- * Get category filter block
109
- *
110
- * @return Mage_Catalog_Block_Layer_Filter_Category
111
- */
112
- protected function _getCategoryFilter()
113
- {
114
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
115
- return parent::_getCategoryFilter();
116
- }
117
- return false;
118
- }
119
-
120
- /**
121
- * Retrieve Price Filter block
122
- *
123
- * @return Mage_Catalog_Block_Layer_Filter_Price
124
- */
125
- protected function _getPriceFilter()
126
- {
127
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
128
- return parent::_getPriceFilter();
129
- }
130
-
131
- return false;
132
- }
133
-
134
- /**
135
- * Check availability display layer block
136
- *
137
- * @return bool
138
- */
139
- public function canShowBlock()
140
- {
141
- if (!Mage::helper('factfinder/search')->getIsEnabled(false)
142
- || (!Mage::helper('factfinder/search')->getIsOnSearchPage() && !Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')) ){
143
- return parent::canShowBlock();
144
- }
145
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
146
- return false;
147
- }
148
- if ($this->getLayer()->getFilterableAttributes()->count()
149
- && $this->getLayer()->getProductCollection()->getSize()) {
150
- return true;
151
- }
152
- return false;
153
- }
154
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Layer/Abstract.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * dynamicaly extends the core class whether Enterprise Search is enabled or not
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
-
22
- if(Mage::helper('factfinder/search')->getIsOnSearchPage()){
23
- if(Mage::helper('factfinder')->isModuleActive('Enterprise_Search')){
24
- class Flagbit_FactFinder_Block_Layer_Abstract extends Enterprise_Search_Block_Catalogsearch_Layer {}
25
- }else{
26
- class Flagbit_FactFinder_Block_Layer_Abstract extends Mage_CatalogSearch_Block_Layer {}
27
- }
28
- }else{
29
- class Flagbit_FactFinder_Block_Layer_Abstract extends Mage_Catalog_Block_Layer_View {}
30
- }
31
-
32
-
33
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Product/List/Crosssell.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Overwritten block.
12
- *
13
- * Replaces the crosssell block. Gets data from FACT-Finder instead of product link collection.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Block_Product_List_Crosssell extends Mage_Catalog_Block_Product_List_Crosssell
22
- {
23
- protected $_recommendationsHandler;
24
-
25
- protected function _prepareLayout()
26
- {
27
- if (Mage::getStoreConfigFlag('factfinder/activation/crosssell')) {
28
- $productIds = array(
29
- Mage::registry('product')->getData(Mage::helper('factfinder/search')->getIdFieldName())
30
- );
31
- $this->_recommendationsHandler = Mage::getSingleton('factfinder/handler_recommendations', $productIds);
32
- }
33
- return parent::_prepareLayout();
34
- }
35
- /**
36
- * Method overwritten. Data is not read from product link collection but from FACT-Finder interface instead.
37
- */
38
- protected function _prepareData()
39
- {
40
-
41
- if (!Mage::getStoreConfigFlag('factfinder/activation/crosssell')) {
42
- return parent::_prepareData();
43
- }
44
- try {
45
- $product = Mage::registry('product');
46
- /* @var $product Mage_Catalog_Model_Product */
47
-
48
- $searchHelper = Mage::helper('factfinder/search');
49
- $idFieldName = $searchHelper->getIdFieldName();
50
-
51
- $this->_itemCollection = Mage::getResourceModel('factfinder/product_recommendation_collection')
52
- ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
53
- ->addStoreFilter();
54
-
55
- $recommendations = $this->_recommendationsHandler->getRecommendations();
56
-
57
- $this->_itemCollection->setRecommendations($recommendations);
58
-
59
- Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
60
-
61
- $this->_itemCollection->load();
62
-
63
- foreach ($this->_itemCollection as $product) {
64
- $product->setDoNotUseCategoryId(true);
65
- }
66
- }
67
- catch (Exception $e) {
68
- Mage::logException($e);
69
- $this->_itemCollection = new Varien_Data_Collection();
70
- }
71
-
72
- return $this;
73
- }
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Product/List/Upsell.php DELETED
@@ -1,142 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class for upselling
12
- *
13
- * Rewritten block - data is now caught by FACT-Finder, passed to normal collection, works quite as if it was the
14
- * default behavior.
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Michael Türk <türk@flagbit.de>
20
- * @version $Id: Search.php 678 2011-08-01 13:02:50Z rudolf_batt $
21
- */
22
- class Flagbit_FactFinder_Block_Product_List_Upsell extends Mage_Catalog_Block_Product_List_Upsell
23
- {
24
- protected $_productCampaignHandler;
25
- protected $_recommendationsHandler;
26
-
27
- protected function _prepareLayout()
28
- {
29
- $productIds = array();
30
-
31
- if(Mage::registry('current_product') instanceof Mage_Catalog_Model_Product){
32
- $productIds[] = Mage::registry('current_product')->getData(Mage::helper('factfinder/search')->getIdFieldName());
33
- }
34
-
35
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')) {
36
- $this->_productCampaignHandler = Mage::getSingleton('factfinder/handler_productDetailCampaign', $productIds);
37
- }
38
-
39
- if (Mage::getStoreConfigFlag('factfinder/activation/upsell')) {
40
- $this->_recommendationsHandler = Mage::getSingleton('factfinder/handler_recommendations', $productIds);
41
- }
42
-
43
- return parent::_prepareLayout();
44
- }
45
-
46
- /**
47
- * Method overwritten. Data is not read from product link collection but from FACT-Finder interface instead.
48
- */
49
- protected function _prepareData()
50
- {
51
- $pushedProducts = array();
52
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')) {
53
- $pushedProducts = $this->getPushedProducts();
54
- }
55
-
56
- $recommendations = array();
57
- if (Mage::getStoreConfigFlag('factfinder/activation/upsell')) {
58
- $recommendations = $this->_recommendationsHandler->getRecommendations();
59
- }
60
-
61
- // if there are no recommendations or pushed products, use default magento upselling
62
- if (empty($recommendations) && empty($pushedProducts)){
63
- return parent::_prepareData();
64
- } else {
65
- // combine recommendations and pushed products
66
- $mergedUpsell = array_merge($pushedProducts, (array) $recommendations);
67
- $this->applyUpsells($mergedUpsell);
68
- }
69
-
70
- return $this;
71
- }
72
-
73
- protected function applyUpsells(array $upsells)
74
- {
75
- try {
76
- $product = Mage::registry('product');
77
- /* @var $product Mage_Catalog_Model_Product */
78
-
79
- // build new FACTFinder_Result with combined data
80
- $recommendations = FF::getInstance('result', $upsells, count($upsells));
81
-
82
- if ($recommendations == null) {
83
- throw new Exception('No recommendations given - check connection to FACT-Finder and FACT-Finder configuration');
84
- }
85
- elseif ($recommendations->getFoundRecordsCount() == 0) {
86
- $this->_itemCollection = new Varien_Data_Collection();
87
- return $this;
88
- }
89
-
90
- $this->_itemCollection = Mage::getResourceModel('factfinder/product_recommendation_collection')->addStoreFilter();
91
-
92
- if ($this->getItemLimit('upsell') > 0) {
93
- $this->_itemCollection->setPageSize($this->getItemLimit('upsell'));
94
- }
95
- $this->_itemCollection->setRecommendations($recommendations);
96
-
97
- Mage::getResourceSingleton('checkout/cart')->addExcludeProductFilter($this->_itemCollection,
98
- Mage::getSingleton('checkout/session')->getQuoteId()
99
- );
100
- $this->_addProductAttributesAndPrices($this->_itemCollection);
101
-
102
- // // Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
103
- Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
104
- $this->_itemCollection->load();
105
-
106
- /**
107
- * Updating collection with desired items
108
- */
109
- Mage::dispatchEvent('catalog_product_upsell', array(
110
- 'product' => $product,
111
- 'collection' => $this->_itemCollection,
112
- 'limit' => $this->getItemLimit()
113
- ));
114
-
115
- foreach ($this->_itemCollection as $product) {
116
- $product->setDoNotUseCategoryId(true);
117
- }
118
- } catch (Exception $e) {
119
- Mage::logException($e);
120
- $this->_itemCollection = new Varien_Data_Collection();
121
- }
122
- }
123
-
124
- /**
125
- * get pushed products to combine with recommendations
126
- *
127
- * @return array
128
- */
129
- protected function getPushedProducts()
130
- {
131
- $pushedProducts = array();
132
-
133
- $_campaigns = $this->_productCampaignHandler->getCampaigns();
134
-
135
- if($_campaigns && $_campaigns->hasPushedProducts()){
136
- $pushedProducts = $_campaigns->getPushedProducts();
137
- }
138
-
139
- return $pushedProducts;
140
- }
141
-
142
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Secondaryresult.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- class Flagbit_FactFinder_Block_Secondaryresult extends Mage_Core_Block_Template
3
- {
4
- protected $_searchHandler;
5
-
6
- protected function _prepareLayout()
7
- {
8
- if(Mage::helper('factfinder/search')->getIsEnabled()){
9
- $this->_searchHandler = Mage::getSingleton('factfinder/handler_secondarySearch');
10
- }
11
- }
12
-
13
- protected function getSecondaryResult($channel)
14
- {
15
- $result = array();
16
- if(Mage::helper('factfinder/search')->getIsEnabled()){
17
- $result = $this->_searchHandler->getSecondarySearchResult($channel);
18
- }
19
-
20
- return $result;
21
- }
22
-
23
- protected function getSecondarySearchAdapter($channel)
24
- {
25
- $adapter = null;
26
- if(Mage::helper('factfinder/search')->getIsEnabled()){
27
- $adapter = $this->_searchHandler->getSecondarySearchAdapter($channel);
28
- }
29
- return $adapter;
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/TagCloud.php DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
- class Flagbit_FactFinder_Block_TagCloud extends Mage_CatalogSearch_Block_Term
3
- {
4
- /**
5
- * @var Flagbit_FactFinder_Model_Handler_TagCloud
6
- */
7
- protected $_tagCloudHandler;
8
-
9
- protected function _prepareLayout()
10
- {
11
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'tagcloud')){
12
- $this->_tagCloudHandler = Mage::getSingleton('factfinder/handler_tagCloud');
13
- }
14
- return parent::_prepareLayout();
15
- }
16
-
17
- /**
18
- * @return Flagbit_FactFinder_Block_TagCloud|Mage_CatalogSearch_Block_Term
19
- */
20
- protected function _loadTerms()
21
- {
22
- if (!Mage::helper('factfinder/search')->getIsEnabled(false, 'tagcloud')) {
23
- return parent::_loadTerms();
24
- }
25
-
26
- if (empty($this->_terms)) {
27
- $this->_terms = $this->_tagCloudHandler->getTerms();
28
-
29
- if (count($this->_terms) == 0)
30
- return $this;
31
-
32
- $this->determineMinMaxPopularity();
33
- }
34
-
35
- return $this;
36
- }
37
-
38
- /**
39
- * Determines minimum and maximum popularity among terms
40
- */
41
- protected function determineMinMaxPopularity()
42
- {
43
- $this->_maxPopularity = 0;
44
- $this->_minPopularity = 1;
45
-
46
- foreach ($this->_terms as $term) {
47
- if ($term->getPopularity() > $this->_maxPopularity)
48
- $this->_maxPopularity = $term->getPopularity();
49
-
50
- if ($term->getPopularity() < $this->_minPopularity)
51
- $this->_minPopularity = $term->getPopularity();
52
- }
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/Tracking.php DELETED
@@ -1,108 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Tracking block class
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <joerg.weller@flagbit.de>
17
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
18
- * @version $Id$
19
- */
20
- class Flagbit_FactFinder_Block_Tracking extends Mage_Core_Block_Template
21
- {
22
-
23
- /**
24
- * get Product Result Collection
25
- *
26
- * @return Flagbit_FactFinder_Model_Mysql4_Search_Collection
27
- */
28
- protected function _getProductResultCollection()
29
- {
30
- return Mage::getSingleton('factfinder/layer')->getProductCollection();
31
- }
32
-
33
- /**
34
- * get Product URL to ID Mapping JSON Object
35
- *
36
- * @return string
37
- */
38
- public function getJsonUrlToIdMappingObject()
39
- {
40
- $data = array();
41
- foreach($this->_getProductResultCollection() as $product){
42
- $data[$product->getProductUrl()] = $product->getId();
43
- }
44
- return Mage::helper('core')->jsonEncode($data);
45
- }
46
-
47
- /**
48
- * get Product and Search Details by ID as JSON Object
49
- *
50
- * @return string
51
- */
52
- public function getJsonDataObject()
53
- {
54
- $searchHelper = Mage::helper('factfinder/search');
55
- $idFieldName = $searchHelper->getIdFieldName();
56
-
57
- $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
58
- if ($customerId) {
59
- $customerId = md5('customer_' . $customerId);
60
- }
61
-
62
- if(Mage::helper('factfinder')->useOldTracking())
63
- {
64
- $dataTemplate = array(
65
- 'query' => $searchHelper->getQuery()->getQueryText(),
66
- 'page' => $searchHelper->getCurrentPage(),
67
- 'sid' => md5(Mage::getSingleton('core/session')->getSessionId()),
68
- 'pageSize' => $searchHelper->getPageLimit(),
69
- 'origPageSize' => $searchHelper->getDefaultPerPageValue(),
70
- 'channel' => Mage::getStoreConfig('factfinder/search/channel'),
71
- 'userId' => $customerId,
72
- 'event' => 'click'
73
- );
74
- } else {
75
- $dataTemplate = array(
76
- 'sourceRefKey' => Mage::getSingleton('core/session')->getFactFinderRefKey(),
77
- 'sid' => md5(Mage::getSingleton('core/session')->getSessionId()),
78
- 'uid' => $customerId,
79
- 'site' => Mage::app()->getStore()->getCode(),
80
- 'event' => FACTFinder_Default_TrackingAdapter::EVENT_INSPECT
81
- );
82
- }
83
-
84
- $data = array();
85
- foreach($this->_getProductResultCollection() as $product){
86
- $key = $product->getId();
87
-
88
- $data[$key] = array(
89
- 'id' => $product->getData($idFieldName),
90
- );
91
-
92
- if(Mage::helper('factfinder')->useOldTracking())
93
- {
94
- $data[$key] += array(
95
- 'pos' => $product->getPosition(),
96
- 'origPos' => $product->getOriginalPosition(),
97
- 'title' => $product->getName(),
98
- 'simi' => $product->getSimilarity()
99
- );
100
- }
101
-
102
- $data[$key] += $dataTemplate;
103
- }
104
-
105
- return Mage::helper('core')->jsonEncode($data);
106
- }
107
-
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/XmlConnect/Catalog/Product/List.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * This class is used to disable Magento´s default apply Filter
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_XmlConnect_Catalog_Product_List extends Mage_XmlConnect_Block_Catalog_Product_List {
22
-
23
- /**
24
- * Retrieve product collection with all prepared data and limitations
25
- *
26
- * @return Mage_Eav_Model_Entity_Collection_Abstract
27
- */
28
- protected function _getProductCollection()
29
- {
30
- if(!Mage::helper('factfinder/search')->getIsEnabled()){
31
- return parent::_getProductCollection();
32
- }
33
-
34
- if (is_null($this->_productCollection)) {
35
- if (strpos($this->getRequest()->getActionName(), 'search') !== false) {
36
- $this->__getSearchProductCollection();
37
- }
38
- else {
39
- parent::_getProductCollection();
40
- }
41
- }
42
- return $this->_productCollection;
43
- }
44
-
45
-
46
- /**
47
- * Retrieve product collection with all prepared data and limitations
48
- *
49
- * @return Mage_Eav_Model_Entity_Collection_Abstract
50
- */
51
- protected function __getSearchProductCollection()
52
- {
53
- if (is_null($this->_productCollection)) {
54
- $filters = array();
55
- $request = $this->getRequest();
56
- $requestParams = $request->getParams();
57
- $layer = $this->getLayer();
58
- if (!$layer) {
59
- return null;
60
- }
61
- $category = $this->getCategory();
62
- if ($category && is_object($category) && $category->getId()) {
63
- $layer->setCurrentCategory($category);
64
- }
65
-
66
- if (!$this->getNeedBlockApplyingFilters()) {
67
- $attributes = $layer->getFilterableAttributes();
68
- /**
69
- * Apply filters
70
- */
71
- foreach ($attributes as $attributeItem) {
72
- $attributeCode = $attributeItem->getAttributeCode();
73
- list($filterModel, $filterBlock) = $this->helper('xmlconnect')->getFilterByKey($attributeCode);
74
-
75
- $filterModel->setLayer($layer)->setAttributeModel($attributeItem);
76
-
77
- $filterParam = parent::REQUEST_FILTER_PARAM_REFIX . $attributeCode;
78
- /**
79
- * Set new request var
80
- */
81
- if (isset($requestParams[$filterParam])) {
82
- $filterModel->setRequestVar($filterParam);
83
- }
84
- $filterModel->apply($request, $filterBlock);
85
- $filters[] = $filterModel;
86
- }
87
-
88
- /**
89
- * Separately apply and save category filter
90
- */
91
- list($categoryFilter, $categoryFilterBlock) = $this->helper('xmlconnect')->getFilterByKey('category');
92
- $filterParam = parent::REQUEST_FILTER_PARAM_REFIX . $categoryFilter->getRequestVar();
93
-
94
- $categoryFilter->setLayer($layer)->setRequestVar($filterParam)
95
- ->apply($this->getRequest(), $categoryFilterBlock);
96
- $filters[] = $categoryFilter;
97
-
98
- $this->_collectedFilters = $filters;
99
- }
100
-
101
- /**
102
- * Products
103
- */
104
- $layer = $this->getLayer();
105
- $collection = $layer->getProductCollection();
106
-
107
- /**
108
- * Add rating and review summary, image attribute, apply sort params
109
- */
110
- $this->_prepareCollection($collection);
111
-
112
- /**
113
- * Apply offset and count
114
- */
115
- $offset = (int)$request->getParam('offset', 0);
116
- $count = (int)$request->getParam('count', 0);
117
- $count = $count <= 0 ? 1 : $count;
118
- if ($offset + $count < $collection->getSize()) {
119
- $this->setHasProductItems(1);
120
- }
121
- $collection->getSelect()->limit($count, $offset);
122
- $collection->setFlag('require_stock_items', true);
123
-
124
- $this->_productCollection = $collection;
125
- }
126
- return $this->_productCollection;
127
- }
128
-
129
-
130
- }
131
-
132
-
133
-
134
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Block/XmlConnect/Catalog/Search.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class
12
- *
13
- * This class is used provide FAC-Finder filters
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Block_XmlConnect_Catalog_Search extends Mage_XmlConnect_Block_Catalog_Search {
22
-
23
-
24
- /**
25
- * Search results xml renderer
26
- * XML also contains filters that can be apply (accorfingly already applyed filters and search query)
27
- * and sort fields
28
- *
29
- * @return string
30
- */
31
- protected function _toHtml()
32
- {
33
- if(!Mage::helper('factfinder/search')->getIsEnabled()){
34
- return parent::_toHtml();
35
- }
36
-
37
- $searchXmlObject = new Mage_XmlConnect_Model_Simplexml_Element('<search></search>');
38
- $filtersXmlObject = new Mage_XmlConnect_Model_Simplexml_Element('<filters></filters>');
39
-
40
- $helper = Mage::helper('catalogsearch');
41
- if (method_exists($helper, 'getEngine')) {
42
- $engine = Mage::helper('catalogsearch')->getEngine();
43
- $isLayeredNavigationAllowed = ($engine instanceof Varien_Object) ? $engine->isLeyeredNavigationAllowed() : true;
44
- }
45
- else {
46
- $isLayeredNavigationAllowed = true;
47
- }
48
-
49
- $request = $this->getRequest();
50
- $requestParams = $request->getParams();
51
- $hasMoreProductItems = 0;
52
-
53
- /**
54
- * Products
55
- */
56
- $productListBlock = $this->getChild('product_list');
57
- $productListBlock->setNeedBlockApplyingFilters(false);
58
- if ($productListBlock) {
59
- $layer = Mage::getSingleton('catalogsearch/layer');
60
- $productsXmlObj = $productListBlock->setLayer($layer)
61
- ->setNeedBlockApplyingFilters(!$isLayeredNavigationAllowed)
62
- ->getProductsXmlObject();
63
- $searchXmlObject->appendChild($productsXmlObj);
64
- $hasMoreProductItems = (int)$productListBlock->getHasProductItems();
65
- }
66
-
67
- $searchXmlObject->addAttribute('has_more_items', $hasMoreProductItems);
68
-
69
- /**
70
- * Filters
71
- */
72
- $showFiltersAndOrders = true;
73
- $reguest = $this->getRequest();
74
- foreach ($reguest->getParams() as $key => $value) {
75
- if (0 === strpos($key, parent::REQUEST_SORT_ORDER_PARAM_REFIX) ||
76
- 0 === strpos($key, parent::REQUEST_FILTER_PARAM_REFIX)) {
77
- $showFiltersAndOrders = false;
78
- break;
79
- }
80
- }
81
- if ($isLayeredNavigationAllowed && $productListBlock && $showFiltersAndOrders) {
82
- $filters = $productListBlock->getCollectedFilters();
83
-
84
- /**
85
- * Render filters xml
86
- */
87
- foreach ($filters as $filter) {
88
- if (!$this->_isFilterItemsHasValues($filter)) {
89
- continue;
90
- }
91
-
92
- $item = $filtersXmlObject->addChild('item');
93
- $item->addChild('name', $searchXmlObject->xmlentities($filter->getName()));
94
- $item->addChild('code', $filter->getRequestVar());
95
- $values = $item->addChild('values');
96
-
97
- foreach ($filter->getItems() as $valueItem) {
98
- $count = (int)$valueItem->getCount();
99
- if (!$count) {
100
- continue;
101
- }
102
- $value = $values->addChild('value');
103
- $value->addChild('id', $valueItem->getValueString());
104
- $value->addChild('label', $searchXmlObject->xmlentities(strip_tags($valueItem->getLabel())));
105
- $value->addChild('count', $count);
106
- }
107
- }
108
- $searchXmlObject->appendChild($filtersXmlObject);
109
- }
110
-
111
- /**
112
- * Sort fields
113
- */
114
- if ($showFiltersAndOrders) {
115
- $searchXmlObject->appendChild($this->getProductSortFieldsXmlObject());
116
- }
117
-
118
- return $searchXmlObject->asNiceXml();
119
- }
120
-
121
- /**
122
- * Overwrite original fallback, because they forgot to return
123
- *
124
- * @return Mage_XmlConnect_Model_Simplexml_Element
125
- */
126
- public function getProductSortFieldsXmlObject()
127
- {
128
- if(method_exists(get_parent_class($this), 'getProductSortFieldsXmlObject')) {
129
- return parent::getProductSortFieldsXmlObject();
130
- }
131
- return parent::getProductSortFeildsXmlObject();
132
- }
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Helper/Data.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Helper class
12
- *
13
- * This helper class provides Translation Methods throw Magento Helper Abstract
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Helper_Data extends Mage_Core_Helper_Abstract {
22
-
23
- /**
24
- * returns Module Status by Module Code
25
- *
26
- * @param string $code Module Code
27
- * @return boolean
28
- */
29
- public function isModuleActive($code)
30
- {
31
- $module = Mage::getConfig()->getNode("modules/$code");
32
- $model = Mage::getConfig()->getNode("global/models/$code");
33
- return $module && $module->is('active') || $model;
34
- }
35
-
36
- /**
37
- * Decide whether old tracking should be used
38
- *
39
- * @return bool
40
- */
41
- public function useOldTracking()
42
- {
43
- $ffVersion = Mage::getStoreConfig('factfinder/search/ffversion');
44
- // to use the new tracking, change the comparison to '$ffVersion < 69'
45
- return ($ffVersion <= 69);
46
- }
47
-
48
- /**
49
- * Decide whether legacy tracking should be used (old tracking for the versions for 6.8 and 6.9)
50
- *
51
- * @return bool
52
- */
53
- public function useLegacyTracking()
54
- {
55
- $ffVersion = Mage::getStoreConfig('factfinder/search/ffversion');
56
- return ($ffVersion >= 68 && $ffVersion <= 69);
57
- }
58
-
59
- /**
60
- * returns the correct path where the tracking should be sent
61
- *
62
- * @return string
63
- */
64
- public function getTrackingUrlPath()
65
- {
66
- $urlPath = 'factfinder/proxy/tracking';
67
- if ($this->useOldTracking() && !$this->useLegacyTracking()) {
68
- // if old tracking is legacy tracking, don't use the scic url
69
- $urlPath = 'factfinder/proxy/scic';
70
- }
71
- return $urlPath;
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Helper/Debug.php DELETED
@@ -1,140 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Helper class
12
- *
13
- * This helper class provides some Methods which allows us
14
- * to debug Modul specific configurations Problems.
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Joerg Weller <weller@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_Helper_Debug extends Mage_Core_Helper_Abstract
23
- implements FACTFinder_Abstract_Logger
24
- {
25
- /**
26
- * Module Configuration File
27
- *
28
- * @var string
29
- */
30
- const MODULE_CONFIG_FILE = 'config.xml';
31
-
32
- /**
33
- * Module Log File
34
- *
35
- * @var string
36
- */
37
- const LOG_FILE_NAME = 'factfinder.log';
38
-
39
- /**
40
- * XML Config Path to Product Identifier Setting
41
- *
42
- * @var string
43
- */
44
- const XML_CONFIG_PATH_DEBUG_MODE = 'factfinder/config/debug';
45
-
46
- /**
47
- * Debug Log to file var/log/factfinder.log
48
- *
49
- * @param $message
50
- * @param $level
51
- * @param $file
52
- * @param $forceLog
53
- */
54
- public function log($message)
55
- {
56
- if (!Mage::getConfig()) {
57
- return;
58
- }
59
- try{
60
- if(Mage::getStoreConfig(self::XML_CONFIG_PATH_DEBUG_MODE)) {
61
- return Mage::log($message, null, self::LOG_FILE_NAME, true);
62
- }
63
- }catch (Exception $e){}
64
-
65
- return $this;
66
- }
67
-
68
- public function trace($message)
69
- {
70
- return $this->log('TRACE: ' . $message);
71
- }
72
- public function debug($message)
73
- {
74
- return $this->log('DEBUG: ' . $message);
75
- }
76
- public function info($message)
77
- {
78
- return $this->log('INFO: ' . $message);
79
- }
80
- public function warn($message)
81
- {
82
- return $this->log('WARNING: ' . $message);
83
- }
84
- public function error($message)
85
- {
86
- return $this->log('ERROR: ' . $message);
87
- }
88
- public function fatal($message)
89
- {
90
- return $this->log('FATAL ERROR: ' . $message);
91
- }
92
-
93
- /**
94
- * get Class Rewrite Conflicts for the current Modul
95
- *
96
- * return array
97
- */
98
- public function getRewriteConflicts()
99
- {
100
- $rewriteConflicts = array();
101
- $xml = simplexml_load_file(Mage::getConfig()->getModuleDir('etc', $this->_getModuleName()).DS.self::MODULE_CONFIG_FILE);
102
- if ($xml instanceof SimpleXMLElement) {
103
- $rewriteNodes = $xml->xpath('//rewrite');
104
-
105
- foreach ($rewriteNodes as $n) {
106
- $nParent = $n->xpath('..');
107
- $module = (string) $nParent[0]->getName();
108
- $nParent2 = $nParent[0]->xpath('..');
109
- $component = (string) $nParent2[0]->getName();
110
- $pathNodes = $n->children();
111
-
112
- foreach ($pathNodes as $pathNode) {
113
-
114
- $path = (string) $pathNode->getName();
115
- $completePath = $module.'/'.$path;
116
-
117
- $rewriteClassName = (string) $pathNode;
118
-
119
- $instance = Mage::getConfig()->getGroupedClassName(
120
- substr($component, 0, -1),
121
- $completePath
122
- );
123
- if($instance != $rewriteClassName){
124
-
125
- try{
126
- $reflector = new $instance();
127
- if($reflector instanceof $rewriteClassName){
128
- continue;
129
- }
130
- }catch (Exception $e){}
131
-
132
- $rewriteConflicts[$rewriteClassName] = $instance;
133
- }
134
- }
135
- }
136
- }
137
- return $rewriteConflicts;
138
- }
139
-
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Helper/Search.php DELETED
@@ -1,421 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Helper class
12
- *
13
- * This helper class provides some Methods which allows us
14
- * to get default und current Values from Toolbar block.
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Joerg Weller <weller@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_Helper_Search extends Mage_Core_Helper_Abstract {
23
-
24
- /**
25
- * XML Config Path to Product Identifier Setting
26
- *
27
- * @var string
28
- */
29
- const XML_CONFIG_PATH_PRODUCT_IDENTIFIER = 'factfinder/config/identifier';
30
-
31
- /**
32
- * XML Config Path to Product Identifier Setting
33
- *
34
- * @var string
35
- */
36
- const XML_CONFIG_PATH_USE_PROXY = 'factfinder/config/proxy';
37
-
38
- const CACHE_TAG = 'FACTFINDER';
39
- const CACHE_ID = "FallbackCache";
40
- const REQUEST_ID_PREFIX = 'FACTFINDER_';
41
-
42
- protected static $_skipFactFinder = null;
43
-
44
- protected static $_isFallbackFeatureActive = null;
45
-
46
- protected static $_failedAttemptRegistered = false;
47
-
48
- /**
49
- * if FACT-Finder enabled?
50
- *
51
- * @param searchPageCheck if true, it will also check whether this is a request for a page with factfinder results
52
- * @param functionality can be one of those: suggest, asn, campaign, clicktracking, tagcloud
53
- * @return boolean true it the specified feature is enabled
54
- */
55
- public function getIsEnabled($searchPageCheck = true, $functionality = '')
56
- {
57
- if (!Mage::getStoreConfigFlag('factfinder/search/enabled')
58
- || Mage::getStoreConfigFlag('advanced/modules_disable_output/Flagbit_FactFinder')
59
- || ($searchPageCheck == true && !$this->getIsOnSearchPage() && !Mage::getStoreConfigFlag('factfinder/activation/navigation'))
60
- || $this->_skipFactFinder()) {
61
- return false;
62
- }
63
-
64
- $result = true;
65
-
66
- if ($functionality) {
67
- switch ($functionality) {
68
- case 'suggest':
69
- $result = Mage::getStoreConfig('factfinder/activation/suggest');
70
- break;
71
- case 'asn':
72
- if (Mage::helper('factfinder/search')->getIsOnSearchPage()) {
73
- $result = Mage::getStoreConfig('factfinder/activation/asn');
74
- }
75
- else {
76
- $result = Mage::getStoreConfig('factfinder/activation/navigation');
77
- }
78
- break;
79
- case 'campaign':
80
- $result = Mage::getStoreConfig('factfinder/activation/campaign');
81
- break;
82
- case 'clicktracking':
83
- $result = Mage::getStoreConfig('factfinder/export/clicktracking');
84
- break;
85
- case 'tagcloud':
86
- $result = Mage::getStoreConfig('factfinder/activation/tagcloud');
87
- break;
88
- }
89
- }
90
-
91
- return $result;
92
- }
93
-
94
- /**
95
- * Determines whether the fallback should be used
96
- *
97
- * @return bool
98
- **/
99
- protected function _isFallbackFeatureActive()
100
- {
101
- if(self::$_isFallbackFeatureActive === null)
102
- {
103
- self::$_isFallbackFeatureActive = Mage::getStoreConfig('factfinder/fallback/use_fallback');
104
- }
105
-
106
- return self::$_isFallbackFeatureActive;
107
- }
108
-
109
- protected function _enableFallback($delay)
110
- {
111
- self::$_skipFactFinder = true;
112
- $nextRetryTimestamp = intval(time() / 60) + $delay;
113
- Mage::app()->saveCache($nextRetryTimestamp, $this->_getCacheId('nextRetryTimestamp'), array(self::CACHE_TAG));
114
- }
115
-
116
- protected function _disableFallback()
117
- {
118
- self::$_skipFactFinder = false;
119
- $nextRetryTimestamp = 0;
120
- Mage::app()->saveCache($nextRetryTimestamp, $this->_getCacheId('nextRetryTimestamp'), array(self::CACHE_TAG));
121
- }
122
-
123
- /**
124
- * Determines whether FACT-Finder should be skipped completely, because it has failed to respond too often
125
- * The check is made lazily so that it will return the same result for every call during one request to Magento.
126
- *
127
- * @return bool
128
- **/
129
- protected function _skipFactFinder()
130
- {
131
- if(self::$_skipFactFinder === null)
132
- {
133
- if(!$this->_isFallbackFeatureActive())
134
- {
135
- self::$_skipFactFinder = false;
136
- }
137
- else
138
- {
139
- $nextRetryTimestamp = intval(Mage::app()->loadCache($this->_getCacheId('nextRetryTimestamp')));
140
- $currentTimestamp = intval(time() / 60);
141
-
142
- self::$_skipFactFinder = ($currentTimestamp <= $nextRetryTimestamp);
143
- }
144
- }
145
-
146
- return self::$_skipFactFinder;
147
- }
148
-
149
- /**
150
- * resets all fallback counter values.
151
- *
152
- * @return void
153
- */
154
- public function resetFailedAttemptCount()
155
- {
156
- $this->_disableFallback();
157
- $this->_saveFailedAttempts(array());
158
- }
159
-
160
- /**
161
- * Registers that FACT-Finder has failed to respond.
162
- * The attempt will be represented as an integer corresponding to attempt's timestamp in minutes.
163
- * Only one failed attempt per lifetime of this object will be registered.
164
- **/
165
- public function registerFailedAttempt()
166
- {
167
- if(self::$_failedAttemptRegistered || !$this->_isFallbackFeatureActive() || $this->_skipFactFinder()) {
168
- return;
169
- }
170
-
171
- $failedAttempts = $this->_loadFailedAttempts();
172
- $failedAttempts = $this->_removeOldEntries($failedAttempts);
173
- $failedAttempts[] = intval(time() / 60);
174
- $this->_saveFailedAttempts($failedAttempts);
175
-
176
- self::$_failedAttemptRegistered = true;
177
- Mage::helper('factfinder/debug')->log('Registered failed attempt to connect to FACT-Finder. '.count($failedAttempts).' failed attempts registered.');
178
-
179
- if (count($failedAttempts) >= 3) {
180
- $delay = Mage::getStoreConfig('factfinder/fallback/wait_time');
181
-
182
- $this->_enableFallback($delay);
183
-
184
- // don't output a warning, if the delay is set to 0 as this would cause a lot of messages during a factfinder downtime
185
- if($delay > 0) {
186
- $this->_outputWarningMessage();
187
- }
188
- }
189
- }
190
-
191
- protected function _outputWarningMessage()
192
- {
193
- $delay = Mage::getStoreConfig('factfinder/fallback/wait_time');
194
-
195
- $title = 'FACT-Finder unreachable! Falling back to Magento\'s search for '.$delay.' minutes.';
196
- $message = 'FACT-Finder did not respond for the third time. Magento will now use its own search for '.$delay.' minutes before trying to reach FACT-Finder again. If the problem persists, please check your FACT-Finder server and the settings in Magento\'s FACT-Finder configuration.';
197
-
198
- $adminNotificationInbox = Mage::getModel('adminnotification/inbox');
199
-
200
- if (method_exists($adminNotificationInbox, 'addMajor')) {
201
- Mage::getModel('adminnotification/inbox')->addMajor($title, $message);
202
- } else {
203
- $severity = Mage_AdminNotification_Model_Inbox::SEVERITY_MAJOR;
204
- $date = date('Y-m-d H:i:s');
205
-
206
- $adminNotificationInbox->parse(array(
207
- array(
208
- 'severity' => $severity,
209
- 'date_added' => $date,
210
- 'title' => $title,
211
- 'description' => $message,
212
- 'url' => '',
213
- 'internal' => true
214
- )
215
- ));
216
- }
217
- }
218
-
219
- protected function _getCacheId($suffix = null)
220
- {
221
- $cacheId = self::REQUEST_ID_PREFIX . self::CACHE_ID;
222
- if ($suffix != null) {
223
- $cacheId .= '_' . $suffix;
224
- }
225
- return $cacheId;
226
- }
227
-
228
- /**
229
- * Loads previously registered failed attempts from cache, if they exist.
230
- * Returns an empty array, otherwise.
231
- *
232
- * @return array of int
233
- **/
234
- protected function _loadFailedAttempts()
235
- {
236
- $cachedContent = Mage::app()->loadCache($this->_getCacheId('failedAttempts'));
237
- $failedAttempts = array();
238
- if($cachedContent) {
239
- $failedAttempts = unserialize($cachedContent);
240
- }
241
-
242
- return $failedAttempts;
243
- }
244
-
245
- /**
246
- * Save failed attempts to cache.
247
- *
248
- * @param array of int failed attempts
249
- **/
250
- public function _saveFailedAttempts($failedAttempts)
251
- {
252
- Mage::app()->saveCache(serialize($failedAttempts), $this->_getCacheId('failedAttempts'), array(self::CACHE_TAG));
253
- }
254
-
255
- /**
256
- * Removes entries from a list of minute-timestamps which are older than 3 minutes
257
- *
258
- * @param array of int entries
259
- **/
260
- protected function _removeOldEntries($entries)
261
- {
262
- $delay = Mage::getStoreConfig('factfinder/fallback/wait_time');
263
- $newEntries = array();
264
-
265
- $minutesTimestamp = intval(time() / 60);
266
- foreach($entries as $entry)
267
- {
268
- if($minutesTimestamp - $entry < 3)
269
- $newEntries[] = $entry;
270
- }
271
-
272
- return $newEntries;
273
- }
274
-
275
- /**
276
- * get Module Status depending on Module
277
- *
278
- * @return boolean
279
- */
280
- public function getIsOnSearchPage()
281
- {
282
- return Mage::app()->getRequest()->getModuleName() == 'catalogsearch' ||
283
- (Mage::app()->getRequest()->getModuleName() == 'xmlconnect' && strpos(Mage::app()->getRequest()->getActionName(), 'search') !== false);
284
- }
285
-
286
-
287
- /**
288
- * get Toolbar Block
289
- *
290
- * @return Mage_Catalog_Block_Product_List_Toolbar
291
- */
292
- protected function _getToolbarBlock()
293
- {
294
- $mainBlock = Mage::app()->getLayout()->getBlock('search.result');
295
- if($mainBlock instanceof Mage_CatalogSearch_Block_Result){
296
- $toolbarBlock = $mainBlock->getListBlock()->getToolbarBlock();
297
- }else{
298
- $toolbarBlock = Mage::app()->getLayout()->createBlock('catalog/product_list_toolbar');
299
- }
300
-
301
- return $toolbarBlock;
302
- }
303
-
304
- /**
305
- * Retrieve default per page values
306
- *
307
- * @return string (comma separated)
308
- */
309
- public function getDefaultPerPageValue()
310
- {
311
- return $this->_getToolbarBlock()->getDefaultPerPageValue();
312
- }
313
-
314
- /**
315
- * get Entity ID Field Name by Configuration or via Entity
316
- *
317
- * @return string
318
- */
319
- public function getIdFieldName()
320
- {
321
- $idFieldName = Mage::getStoreConfig(self::XML_CONFIG_PATH_PRODUCT_IDENTIFIER);
322
- if(!$idFieldName){
323
- $idFieldName = $this->getEntity()->getIdFieldName();
324
- }
325
- return $idFieldName;
326
- }
327
-
328
- /**
329
- * get FACT-Finder Suggest URL
330
- *
331
- * @return string
332
- */
333
- public function getSuggestUrl()
334
- {
335
- if ($this->isSuggestProxyActivated()) {
336
- $params = array();
337
- if (Mage::app()->getStore()->isCurrentlySecure()) {
338
- $params['_secure'] = true;
339
- }
340
- $url = $this->_getUrl('factfinder/proxy/suggest', $params);
341
- } else {
342
- $url = Mage::getSingleton('factfinder/facade')->getSuggestUrl();
343
- if (Mage::app()->getStore()->isCurrentlySecure()) {
344
- $url = preg_replace('/^http:/', 'https:', $url);
345
- }
346
- }
347
- return $url;
348
- }
349
-
350
- /**
351
- * @return bool
352
- */
353
- public function isSuggestProxyActivated()
354
- {
355
- return Mage::getStoreConfig(self::XML_CONFIG_PATH_USE_PROXY);
356
- }
357
-
358
- /**
359
- * get current Order
360
- *
361
- * @return string
362
- */
363
- public function getCurrentOrder()
364
- {
365
- return $this->_getToolbarBlock()->getCurrentOrder();
366
- }
367
-
368
- /**
369
- * get current Order Direction
370
- *
371
- * @return string
372
- */
373
- public function getCurrentDirection()
374
- {
375
- return $this->_getToolbarBlock()->getCurrentDirection();
376
- }
377
-
378
- /**
379
- * get Page Limit
380
- *
381
- * @return int
382
- */
383
- public function getPageLimit()
384
- {
385
- $limit = $this->_getToolbarBlock()->getLimit();
386
- if ($limit == 'all') {
387
- $limit = 2*3*4*5*6; //a lot of products working for each layout
388
- }
389
- return $limit;
390
- }
391
-
392
- /**
393
- * get current Page Number
394
- *
395
- * @return int
396
- */
397
- public function getCurrentPage()
398
- {
399
- return $this->_getToolbarBlock()->getCurrentPage();
400
- }
401
-
402
- /**
403
- * Retrieve query model object
404
- *
405
- * @return Mage_CatalogSearch_Model_Query
406
- */
407
- public function getQuery()
408
- {
409
- return Mage::helper('catalogsearch')->getQuery();
410
- }
411
-
412
- /**
413
- * Retrieve query model object
414
- *
415
- * @return String
416
- */
417
- public function getQueryText()
418
- {
419
- return Mage::helper('catalogsearch')->getQueryText();
420
- }
421
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Export/Price.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Price export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Export_Price extends Mage_Core_Model_Mysql4_Abstract {
22
-
23
- /**
24
- * defines Export Columns
25
- * @var array
26
- */
27
- protected $_exportColumns = array('entity_id', 'customer_group_id', 'final_price', 'min_price');
28
-
29
- /**
30
- * Resource initialization
31
- */
32
- protected function _construct(){
33
- $this->_setResource('core');
34
- }
35
-
36
- /**
37
- * add CSV Row
38
- *
39
- * @param array $data
40
- */
41
- protected function _addCsvRow($data)
42
- {
43
- foreach($data as &$item){
44
- $item = str_replace(array("\r", "\n", "\""), ' ', addcslashes(strip_tags($item), '"'));
45
- }
46
-
47
- echo '"'.implode('";"', $data).'"'."\n";
48
- }
49
-
50
- /**
51
- * export Product Prices
52
- * direct Output as CSV
53
- *
54
- * @param int $storeId Store View Id
55
- */
56
- public function doExport($storeId = null)
57
- {
58
- $this->_addCsvRow($this->_exportColumns);
59
- for($i=1; $prices = $this->_getPrices($storeId, $i); $i++){
60
- foreach($prices as $price){
61
- $this->_addCsvRow($price);
62
- }
63
- }
64
- }
65
-
66
- /**
67
- * get Prices from Price Index Table
68
- *
69
- * @param int $storeId Store ID
70
- * @param int $part
71
- * @param int $limit
72
- * @return array
73
- */
74
- protected function _getPrices($storeId, $part = 1, $limit = 100){
75
-
76
- $store = Mage::app()->getStore($storeId);
77
- $select = $this->_getWriteAdapter()->select()
78
- ->from(
79
- array('e' => $this->getTable('catalog/product_index_price')),
80
- $this->_exportColumns);
81
-
82
- if($storeId !== null){
83
- $select->where('e.website_id = ?', $store->getWebsiteId());
84
- }
85
-
86
- $select->limitPage($part, $limit)
87
- ->order('e.entity_id');
88
-
89
- return $this->_getWriteAdapter()->fetchAll($select);
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Export/Product.php DELETED
@@ -1,616 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Product export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Export_Product extends Mage_CatalogSearch_Model_Mysql4_Fulltext {
22
-
23
- /**
24
- * Option ID to Value Mapping Array
25
- * @var mixed
26
- */
27
- protected $_optionIdToValue = null;
28
-
29
- /**
30
- * Products to Category Path Mapping
31
- *
32
- * @var mixed
33
- */
34
- protected $_productsToCategoryPath = null;
35
-
36
- /**
37
- * Category Names by ID
38
- * @var mixed
39
- */
40
- protected $_categoryNames = null;
41
-
42
- /**
43
- * export attribute codes
44
- * @var mixed
45
- */
46
- protected $_exportAttributeCodes = null;
47
-
48
- /**
49
- * export attribute objects
50
- * @var mixed
51
- */
52
- protected $_exportAttributes = null;
53
-
54
- /**
55
- * helper to generate the image urls
56
- * @var Mage_Catalog_Helper_Image
57
- */
58
- protected $_imageHelper = null;
59
-
60
- /**
61
- * add CSV Row
62
- *
63
- * @param array $data
64
- */
65
- protected function _addCsvRow($data)
66
- {
67
- foreach ($data as &$item) {
68
- $item = str_replace(array("\r", "\n", "\""), array(' ', ' ', "''"), trim( strip_tags($item), ';') );
69
- }
70
-
71
- echo '"'.implode('";"', $data).'"'."\n";
72
- }
73
-
74
- /**
75
- * get Option Text by Option ID
76
- *
77
- * @param int $optionId Option ID
78
- * @param int $storeId Store ID
79
- * @return string
80
- */
81
- protected function _getAttributeOptionText($optionId, $storeId)
82
- {
83
- $value = '';
84
- if (intval($optionId)) {
85
- if ($this->_optionIdToValue === null) {
86
- /*@var $optionCollection Mage_Eav_Model_Mysql4_Entity_Attribute_Option_Collection */
87
- $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection');
88
- $optionCollection->setStoreFilter($storeId);
89
- $this->_optionIdToValue = array();
90
- foreach ($optionCollection as $option) {
91
- $this->_optionIdToValue[$option->getId()] = $option->getValue();
92
- }
93
- }
94
- $value = isset($this->_optionIdToValue[$optionId]) ? $this->_optionIdToValue[$optionId] : '';
95
- }
96
- return $value;
97
- }
98
-
99
- /**
100
- * get CSV Header Array
101
- *
102
- * @param int $storeId
103
- * @return array
104
- */
105
- protected function _getExportAttributes($storeId = null)
106
- {
107
- if($this->_exportAttributeCodes === null){
108
- $headerDefault = array('id', 'parent_id', 'sku', 'category', 'filterable_attributes', 'searchable_attributes');
109
- $headerDynamic = array();
110
-
111
- if (Mage::getStoreConfigFlag('factfinder/export/urls', $storeId)) {
112
- $headerDefault[] = 'image';
113
- $headerDefault[] = 'deeplink';
114
- $this->_imageHelper = Mage::helper('catalog/image');
115
- }
116
-
117
- // get dynamic Attributes
118
- foreach ($this->_getSearchableAttributes(null, 'system', $storeId) as $attribute) {
119
- if (in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility'))) {
120
- continue;
121
- }
122
- $headerDynamic[] = $attribute->getAttributeCode();
123
- }
124
-
125
- // compare dynamic with setup attributes
126
- $headerSetup = Mage::helper('factfinder/backend')->makeArrayFieldValue(Mage::getStoreConfig('factfinder/export/attributes', $storeId));
127
- $setupUpdate = false;
128
- foreach($headerDynamic as $code){
129
- if(in_array($code, $headerSetup)){
130
- continue;
131
- }
132
- $headerSetup[$code]['attribute'] = $code;
133
- $setupUpdate = true;
134
- }
135
-
136
- // remove default attributes from setup
137
- foreach($headerDefault as $code){
138
- if(array_key_exists($code, $headerSetup)){
139
- unset($headerSetup[$code]);
140
- $setupUpdate = true;
141
- }
142
- }
143
-
144
- if($setupUpdate === true){
145
- Mage::getModel('core/config')->saveConfig('factfinder/export/attributes', Mage::helper('factfinder/backend')->makeStorableArrayFieldValue($headerSetup), 'stores', $storeId);
146
- }
147
-
148
- $this->_exportAttributeCodes = array_merge($headerDefault, array_keys($headerSetup));
149
- }
150
- return $this->_exportAttributeCodes;
151
- }
152
-
153
-
154
- /**
155
- * export Product Data with Attributes
156
- * direct Output as CSV
157
- *
158
- * @param int $storeId Store View Id
159
- */
160
- public function doExport($storeId = null)
161
- {
162
- $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
163
- $exportImageAndDeeplink = Mage::getStoreConfigFlag('factfinder/export/urls', $storeId);
164
- if ($exportImageAndDeeplink) {
165
- $imageType = Mage::getStoreConfig('factfinder/export/suggest_image_type', $storeId);
166
- $imageSize = (int) Mage::getStoreConfig('factfinder/export/suggest_image_size', $storeId);
167
- }
168
-
169
- $header = $this->_getExportAttributes($storeId);
170
- $this->_addCsvRow($header);
171
-
172
- // preparesearchable attributes
173
- $staticFields = array();
174
- foreach ($this->_getSearchableAttributes('static', 'system', $storeId) as $attribute) {
175
- $staticFields[] = $attribute->getAttributeCode();
176
- }
177
- $dynamicFields = array(
178
- 'int' => array_keys($this->_getSearchableAttributes('int')),
179
- 'varchar' => array_keys($this->_getSearchableAttributes('varchar')),
180
- 'text' => array_keys($this->_getSearchableAttributes('text')),
181
- 'decimal' => array_keys($this->_getSearchableAttributes('decimal')),
182
- 'datetime' => array_keys($this->_getSearchableAttributes('datetime')),
183
- );
184
-
185
- // status and visibility filter
186
- $visibility = $this->_getSearchableAttribute('visibility');
187
- $status = $this->_getSearchableAttribute('status');
188
- $visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
189
- $statusVals = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();
190
-
191
- $lastProductId = 0;
192
- while (true) {
193
- $products = $this->_getSearchableProducts($storeId, $staticFields, null, $lastProductId);
194
- if (!$products) {
195
- break;
196
- }
197
-
198
- $productRelations = array();
199
- foreach ($products as $productData) {
200
- $lastProductId = $productData['entity_id'];
201
- $productAttributes[$productData['entity_id']] = $productData['entity_id'];
202
- $productChilds = $this->_getProductChildIds($productData['entity_id'], $productData['type_id']);
203
- $productRelations[$productData['entity_id']] = $productChilds;
204
- if ($productChilds) {
205
- foreach ($productChilds as $productChild) {
206
- $productAttributes[$productChild['entity_id']] = $productChild;
207
- }
208
- }
209
- }
210
-
211
- $productAttributes = $this->_getProductAttributes($storeId, array_keys($productAttributes), $dynamicFields);
212
- foreach ($products as $productData) {
213
- if (!isset($productAttributes[$productData['entity_id']])) {
214
- continue;
215
- }
216
- $productAttr = $productAttributes[$productData['entity_id']];
217
-
218
- if (!isset($productAttr[$visibility->getId()]) || !in_array($productAttr[$visibility->getId()], $visibilityVals)) {
219
- continue;
220
- }
221
- if (!isset($productAttr[$status->getId()]) || !in_array($productAttr[$status->getId()], $statusVals)) {
222
- continue;
223
- }
224
-
225
- $productIndex = array(
226
- $productData['entity_id'],
227
- $productData[$idFieldName],
228
- $productData['sku'],
229
- $this->_getCategoryPath($productData['entity_id'], $storeId),
230
- $this->_formatFilterableAttributes($this->_getSearchableAttributes(null, 'filterable'), $productAttr, $storeId),
231
- $this->_formatSearchableAttributes($this->_getSearchableAttributes(null, 'searchable'), $productAttr, $storeId)
232
- );
233
-
234
- if ($exportImageAndDeeplink) {
235
- $product = Mage::getModel("catalog/product");
236
- $product->setStoreId($storeId);
237
- $product->load($productData['entity_id']);
238
-
239
- $productIndex[] = (string) $this->_imageHelper->init($product, $imageType)->resize($imageSize);
240
- $productIndex[] = $product->getProductUrl();
241
- }
242
-
243
- $this->_getAttributesRowArray($productIndex, $productAttr, $storeId);
244
-
245
- $this->_addCsvRow($productIndex);
246
-
247
- if ($productChilds = $productRelations[$productData['entity_id']]) {
248
- foreach ($productChilds as $productChild) {
249
- if (isset($productAttributes[$productChild['entity_id']])) {
250
- /* should be used if sub products should not be exported because of their status
251
- $subProductAttr = $productAttributes[$productChild[ 'entity_id' ]];
252
- if (!isset($subProductAttr[$status->getId()]) || !in_array($subProductAttr[$status->getId()], $statusVals)) {
253
- continue;
254
- } */
255
-
256
- $subProductIndex = array(
257
- $productChild['entity_id'],
258
- $productData[$idFieldName],
259
- $productChild['sku'],
260
- $this->_getCategoryPath($productData['entity_id'], $storeId),
261
- $this->_formatFilterableAttributes($this->_getSearchableAttributes(null, 'filterable'), $productAttributes[$productChild['entity_id']], $storeId),
262
- $this->_formatSearchableAttributes($this->_getSearchableAttributes(null, 'searchable'), $productAttributes[$productChild['entity_id']], $storeId)
263
- );
264
- if ($exportImageAndDeeplink) {
265
- //dont need to add image and deeplink to child product, just add empty values
266
- $subProductIndex[] = '';
267
- $subProductIndex[] = '';
268
- }
269
- $this->_getAttributesRowArray($subProductIndex, $productAttributes[$productChild['entity_id']], $storeId);
270
-
271
- $this->_addCsvRow($subProductIndex);
272
- }
273
- }
274
- }
275
- }
276
-
277
- unset($products);
278
- unset($productAttributes);
279
- unset($productRelations);
280
- flush();
281
- }
282
- }
283
-
284
- protected function _formatSearchableAttributes($attributes, $values, $storeId=null)
285
- {
286
- $returnArray = array();
287
- foreach ($attributes as $attribute) {
288
- $value = isset($values[$attribute->getId()]) ? $values[$attribute->getId()] : null;
289
- if (!$value || in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility', 'price'))) {
290
- continue;
291
- }
292
- $attributeValue = $this->_getAttributeValue($attribute->getId(), $value, $storeId);
293
- if (strval($attributeValue) != "") {
294
- $returnArray[] = $attributeValue;
295
- }
296
- }
297
- return implode(',', $returnArray);
298
- }
299
-
300
- protected function _formatFilterableAttributes($attributes, $values, $storeId=null)
301
- {
302
- $returnArray = array();
303
- foreach ($attributes as $attribute) {
304
- $value = isset($values[$attribute->getId()]) ? $values[$attribute->getId()] : null;
305
- if (!$value || in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility', 'price'))) {
306
- continue;
307
- }
308
- $attributeValue = $this->_getAttributeValue($attribute->getId(), $value, $storeId);
309
- $attributeValues = array();
310
- if (strpos($attributeValue, '|') !== false) {
311
- $attributeValues = explode('|', $attributeValue);
312
- } else {
313
- $attributeValues[] = $attributeValue;
314
- }
315
-
316
- foreach ($attributeValues AS $value) {
317
- if (strval($value) != "") {
318
- $returnArray[] = $attribute->getAttributeCode().'='.$value;
319
- }
320
- }
321
- }
322
- return implode('|', $returnArray);
323
- }
324
-
325
- /**
326
- * Retrieve Searchable attributes
327
- *
328
- * @param string $backendType
329
- * @param string $type possible Types: system, sortable, filterable, searchable
330
- * @return array
331
- */
332
- protected function _getSearchableAttributes($backendType = null, $type = null, $storeId = null)
333
- {
334
- if (is_null($this->_searchableAttributes)) {
335
- $this->_searchableAttributes = array();
336
- $entityType = $this->getEavConfig()->getEntityType('catalog_product');
337
- $entity = $entityType->getEntity();
338
-
339
- $userDefinedAttributes = array_keys(Mage::helper('factfinder/backend')->makeArrayFieldValue(Mage::getStoreConfig('factfinder/export/attributes', $storeId)));
340
-
341
- $whereCond = array(
342
- $this->_getWriteAdapter()->quoteInto('additional_table.is_searchable=? or additional_table.is_filterable=? or additional_table.used_for_sort_by=?', 1),
343
- $this->_getWriteAdapter()->quoteInto('main_table.attribute_code IN(?)', array_merge(array('status', 'visibility'), $userDefinedAttributes))
344
- );
345
-
346
- $select = $this->_getWriteAdapter()->select()
347
- ->from(array('main_table' => $this->getTable('eav/attribute')))
348
- ->join(
349
- array('additional_table' => $this->getTable('catalog/eav_attribute')),
350
- 'additional_table.attribute_id = main_table.attribute_id'
351
- )
352
- ->where('main_table.entity_type_id=?', $entityType->getEntityTypeId())
353
- ->where(join(' OR ', $whereCond))
354
- ->order('main_table.attribute_id', 'asc');
355
-
356
- $attributesData = $this->_getWriteAdapter()->fetchAll($select);
357
- $this->getEavConfig()->importAttributesData($entityType, $attributesData);
358
- foreach ($attributesData as $attributeData) {
359
- $attributeCode = $attributeData['attribute_code'];
360
- $attribute = $this->getEavConfig()->getAttribute($entityType, $attributeCode);
361
- $attribute->setEntity($entity);
362
- $this->_searchableAttributes[$attribute->getId()] = $attribute;
363
- }
364
- unset($attributesData);
365
- }
366
-
367
- if (!is_null($type) || !is_null($backendType)) {
368
- $attributes = array();
369
- foreach ($this->_searchableAttributes as $attribute) {
370
-
371
- if (!is_null($backendType)
372
- && $attribute->getBackendType() != $backendType) {
373
- continue;
374
- }
375
-
376
- switch($type) {
377
-
378
- case "system":
379
- if ($attribute->getIsUserDefined()
380
- && !$attribute->getUsedForSortBy()) {
381
- continue 2;
382
- }
383
- break;
384
-
385
- case "sortable":
386
- if (!$attribute->getUsedForSortBy()) {
387
- continue 2;
388
- }
389
- break;
390
-
391
- case "filterable":
392
- if (!$attribute->getIsFilterableInSearch()
393
- || in_array($attribute->getAttributeCode(), $this->_getExportAttributes())) {
394
- continue 2;
395
- }
396
- break;
397
-
398
- case "searchable":
399
- if (!$attribute->getIsUserDefined()
400
- || !$attribute->getIsSearchable()
401
- || in_array($attribute->getAttributeCode(), $this->_getExportAttributes())) {
402
- continue 2;
403
- }
404
- break;
405
- }
406
-
407
- $attributes[$attribute->getId()] = $attribute;
408
- }
409
- return $attributes;
410
- }
411
- return $this->_searchableAttributes;
412
- }
413
-
414
- /**
415
- * Get Category Path by Product ID
416
- *
417
- * @param int $productId
418
- * @param int $storeId
419
- * @return string
420
- */
421
- protected function _getCategoryPath($productId, $storeId = null)
422
- {
423
-
424
- if ($this->_categoryNames === null) {
425
- $categoryCollection = Mage::getResourceModel('catalog/category_attribute_collection');
426
- $categoryCollection->getSelect()->where("attribute_code IN('name', 'is_active')");
427
-
428
- foreach ($categoryCollection as $categoryModel) {
429
- ${$categoryModel->getAttributeCode().'Model'} = $categoryModel;
430
- }
431
-
432
- $select = $this->_getReadAdapter()->select()
433
- ->from(
434
- array('main' => $nameModel->getBackendTable()),
435
- array('entity_id', 'value')
436
- )
437
- ->join(
438
- array('e' => $is_activeModel->getBackendTable()),
439
- 'main.entity_id=e.entity_id AND (e.store_id = 0 OR e.store_id = '.$storeId.') AND e.attribute_id='.$is_activeModel->getAttributeId(),
440
- null
441
- )
442
- ->where('main.attribute_id=?', $nameModel->getAttributeId())
443
- ->where('e.value=?', '1')
444
- ->where('main.store_id = 0 OR main.store_id = ?', $storeId);
445
-
446
- $this->_categoryNames = $this->_getReadAdapter()->fetchPairs($select);
447
- }
448
-
449
- if ($this->_productsToCategoryPath === null) {
450
- $select = $this->_getReadAdapter()->select()
451
- ->from(
452
- array('main' => $this->getTable('catalog/category_product_index')),
453
- array('product_id')
454
- )
455
- ->join(
456
- array('e' => $this->getTable('catalog/category')),
457
- 'main.category_id=e.entity_id',
458
- null
459
- )
460
- ->columns(array('e.path' => new Zend_Db_Expr('GROUP_CONCAT(e.path)')))
461
- ->where(
462
- 'main.visibility IN(?)',
463
- array(
464
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
465
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
466
- )
467
- )
468
- ->where('main.store_id = ?', $storeId)
469
- ->where('e.path LIKE \'1/' . Mage::app()->getStore($storeId)->getRootCategoryId() .'/%\'')
470
- ->group('main.product_id');
471
-
472
- $this->_productsToCategoryPath = $this->_getReadAdapter()->fetchPairs($select);
473
- }
474
-
475
- $value = '';
476
- if (isset($this->_productsToCategoryPath[$productId])) {
477
- $paths = explode(',', $this->_productsToCategoryPath[$productId]);
478
- foreach ($paths as $path) {
479
- $categoryIds = explode('/', $path);
480
- $categoryIdsCount = count($categoryIds);
481
- $categoryPath = '';
482
- for($i=2;$i < $categoryIdsCount;$i++) {
483
- if (!isset($this->_categoryNames[$categoryIds[$i]])) {
484
- continue 2;
485
- }
486
- $categoryPath .= urlencode(trim($this->_categoryNames[$categoryIds[$i]])).'/';
487
- }
488
- if ($categoryIdsCount > 2) {
489
- $value .= rtrim($categoryPath,'/').'|';
490
- }
491
- }
492
- $value = trim($value, '|');
493
- }
494
-
495
- return $value;
496
- }
497
-
498
- /**
499
- * Return all product children ids
500
- *
501
- * @param int $productId Product Entity Id
502
- * @param string $typeId Super Product Link Type
503
- * @return array
504
- */
505
- protected function _getProductChildIds($productId, $typeId)
506
- {
507
- $typeInstance = $this->_getProductTypeInstance($typeId);
508
- $relation = $typeInstance->isComposite()
509
- ? $typeInstance->getRelationInfo()
510
- : false;
511
-
512
- if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) {
513
- $select = $this->_getReadAdapter()->select()
514
- ->from(
515
- array('main' => $this->getTable($relation->getTable())),
516
- array($relation->getChildFieldName()))
517
-
518
- ->join(
519
- array('e' => $this->getTable('catalog/product')),
520
- 'main.'.$relation->getChildFieldName().'=e.entity_id',
521
- array('entity_id', 'type_id', 'sku')
522
- )
523
-
524
- ->where("{$relation->getParentFieldName()}=?", $productId);
525
- if (!is_null($relation->getWhere())) {
526
- $select->where($relation->getWhere());
527
- }
528
- return $this->_getReadAdapter()->fetchAll($select);
529
- }
530
-
531
- return null;
532
- }
533
-
534
- /**
535
- * Retrieve attribute source value for search
536
- * This method is mostly copied from Mage_CatalogSearch_Model_Resource_Fulltext, but it also retrieves attribute values from non-searchable/non-filterable attributes
537
- *
538
- * @param int $attributeId
539
- * @param mixed $value
540
- * @param int $storeId
541
- * @return mixed
542
- */
543
- protected function _getAttributeValue($attributeId, $value, $storeId)
544
- {
545
- $attribute = $this->_getSearchableAttribute($attributeId);
546
- if (!$attribute->getIsSearchable() && $attribute->getAttributeCode() == 'visibility') {
547
- return $value;
548
- }
549
-
550
- if ($attribute->usesSource()) {
551
- if ($this->_engine !== null && method_exists($this->_engine, 'allowAdvancedIndex') && $this->_engine->allowAdvancedIndex()) {
552
- return $value;
553
- }
554
-
555
- $attribute->setStoreId($storeId);
556
- $value = $attribute->getSource()->getOptionText($value);
557
-
558
- if (is_array($value)) {
559
- $value = implode($this->_separator, $value);
560
- } elseif (empty($value)) {
561
- $inputType = $attribute->getFrontend()->getInputType();
562
- if ($inputType == 'select' || $inputType == 'multiselect') {
563
- return null;
564
- }
565
- }
566
- } elseif ($attribute->getBackendType() == 'datetime') {
567
- $value = $this->_getStoreDate($storeId, $value);
568
- } else {
569
- $inputType = $attribute->getFrontend()->getInputType();
570
- if ($inputType == 'price') {
571
- $value = Mage::app()->getStore($storeId)->roundPrice($value);
572
- }
573
- }
574
-
575
- // Add spaces before HTML Tags, so that strip_tags() does not join word which were in different block elements
576
- // Additional spaces are not an issue, because they will be removed in the next step anyway
577
- $value = preg_replace('/</u', ' <', $value);
578
-
579
- $value = preg_replace("#\s+#siu", ' ', trim(strip_tags($value)));
580
-
581
- return $value;
582
- }
583
-
584
- /**
585
- * get Attribute Row Array
586
- *
587
- * @param array $dataArray Export row Array
588
- * @param array $attributes Attributes Array
589
- * @param int $storeId Store ID
590
- */
591
- protected function _getAttributesRowArray(&$dataArray, $values, $storeId=null)
592
- {
593
- // get attributes objects assigned to their position at the export
594
- if ($this->_exportAttributes == null) {
595
- $this->_exportAttributes = array_fill(0, sizeof($this->_getExportAttributes()), null);
596
-
597
- $attributeCodes = array_flip($this->_getExportAttributes());
598
- foreach ($this->_getSearchableAttributes() as $attribute) {
599
- if (isset($attributeCodes[$attribute->getAttributeCode()]) && !in_array($attribute->getAttributeCode(), array('sku', 'status', 'visibility'))) {
600
- $this->_exportAttributes[$attributeCodes[$attribute->getAttributeCode()]] = $attribute;
601
- }
602
- }
603
- }
604
- // fill dataArray with the values of the attributes that should be exported
605
- foreach($this->_exportAttributes AS $pos => $attribute) {
606
- if ($attribute != null) {
607
- $value = isset($values[$attribute->getId()]) ? $values[$attribute->getId()] : null;
608
- $dataArray[$pos] = $this->_getAttributeValue($attribute->getId(), $value, $storeId);
609
- } else if (!array_key_exists($pos, $dataArray)) {
610
- // it is very unlikely that an attribute exists in the header but is not delivered by "getSearchableAttributes",
611
- // but actually it might be a result of a broken database or something like that..
612
- $dataArray[$pos] = null;
613
- }
614
- }
615
- }
616
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Export/Stock.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Stock export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Export_Stock extends Mage_Core_Model_Mysql4_Abstract {
22
-
23
- /**
24
- * defines Export Columns
25
- * @var array
26
- */
27
- protected $_exportColumns = array('product_id', 'qty', 'stock_status');
28
-
29
- /**
30
- * Resource initialization
31
- */
32
- protected function _construct(){
33
- $this->_setResource('core');
34
- }
35
-
36
- /**
37
- * add CSV Row
38
- *
39
- * @param array $data
40
- */
41
- protected function _addCsvRow($data)
42
- {
43
- foreach($data as &$item){
44
- $item = str_replace(array("\r", "\n", "\""), ' ', addcslashes(strip_tags($item), '"'));
45
- }
46
-
47
- echo '"'.implode('";"', $data).'"'."\n";
48
- }
49
-
50
- /**
51
- * export Stock Data
52
- * direct Output as CSV
53
- *
54
- * @param int $storeId Store Id
55
- */
56
- public function doExport($storeId = null)
57
- {
58
- $this->_addCsvRow($this->_exportColumns);
59
- for($i=1; $stocks = $this->_getStockData($storeId, $i); $i++){
60
- foreach($stocks as $stock){
61
- $this->_addCsvRow($stock);
62
- }
63
- }
64
- }
65
-
66
- /**
67
- * get Stocks from Stock Index Table
68
- *
69
- * @param int $storeId Store ID
70
- * @param int $part
71
- * @param int $limit
72
- * @return array
73
- */
74
- protected function _getStockData($storeId, $part = 1, $limit = 100){
75
-
76
- $store = Mage::app()->getStore($storeId);
77
- $select = $this->_getWriteAdapter()->select()
78
- ->from(
79
- array('e' => $this->getTable('cataloginventory/stock_status')),
80
- $this->_exportColumns);
81
-
82
- if($storeId !== null){
83
- $select->where('e.website_id = ?', $store->getWebsiteId());
84
- }
85
-
86
- $select->limitPage($part, $limit)
87
- ->order('e.product_id');
88
-
89
- return $this->_getWriteAdapter()->fetchAll($select);
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Facade.php DELETED
@@ -1,549 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- require_once BP.DS.'lib'.DS.'FACTFinder'.DS.'Loader.php';
11
-
12
- /**
13
- * Model class
14
- *
15
- * Facade that hides FACT-Finder API Framework for Magento
16
- *
17
- * @category Mage
18
- * @package Flagbit_FactFinder
19
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
20
- * @author Joerg Weller <weller@flagbit.de>
21
- * @version $Id: Facade.php 906 2011-09-30 14:10:05Z tuerk $
22
- */
23
- class Flagbit_FactFinder_Model_Facade
24
- {
25
- /**
26
- * Two-dimensional array of FACT-Finder adapters
27
- * First-dimension key corresponds to type
28
- * Second-dimension key corresponds to channel
29
- * @var array of FACTFinder_Abstract_Adapter
30
- */
31
- protected $_adapters = array();
32
-
33
- /**
34
- * Key corresponds to channel
35
- * @var array of FACTFinder_Http_StatusHelper
36
- */
37
- protected $_statusHelpers = array();
38
-
39
- /**
40
- * @var FACTFinder_Abstract_Configuration
41
- */
42
- protected $_config = null;
43
-
44
- /**
45
- * @var FACTFinder_ParametersParser
46
- */
47
- protected $_paramsParser = null;
48
-
49
- /**
50
- * @var FACTFinder_Http_UrlBuilder
51
- */
52
- protected $_urlBuilder = null;
53
-
54
- /**
55
- * logger object to log all module internals
56
- * @var FACTFinder_Abstract_Logger
57
- */
58
- protected $_logger = null;
59
-
60
- /**
61
- * map between known adapters and its state based on its parameters
62
- * @var array
63
- */
64
- protected $_paramHashes = array();
65
-
66
- /**
67
- * @var boolean is set to true, if caching is enabled and can be used
68
- */
69
- private $_useCaching = null;
70
-
71
- public function __construct($arg = null)
72
- {
73
- if ($arg === null || !($arg instanceof FACTFinder_Abstract_Logger)) {
74
- $arg = Mage::helper('factfinder/debug');
75
- }
76
- FF::setLogger($arg);
77
- $this->_logger = $arg;
78
- }
79
-
80
- public function getSearchAdapter($channel = null)
81
- {
82
- return $this->_getAdapter("search", $channel);
83
- }
84
-
85
- public function getScicAdapter($channel = null)
86
- {
87
- return $this->_getAdapter("scic", $channel);
88
- }
89
-
90
- public function getSuggestAdapter($channel = null)
91
- {
92
- return $this->_getAdapter("suggest", $channel);
93
- }
94
-
95
- public function getRecommendationAdapter($channel = null)
96
- {
97
- return $this->_getAdapter("recommendation", $channel);
98
- }
99
-
100
- public function getTagCloudAdapter($channel = null)
101
- {
102
- return $this->_getAdapter("tagCloud", $channel);
103
- }
104
-
105
- public function getCompareAdapter($channel = null)
106
- {
107
- return $this->_getAdapter("compare", $channel);
108
- }
109
-
110
- public function getImportAdapter($channel = null)
111
- {
112
- return $this->_getAdapter("import", $channel);
113
- }
114
-
115
- public function getProductCampaignAdapter($channel = null)
116
- {
117
- return $this->_getAdapter("productCampaign", $channel);
118
- }
119
-
120
- public function getSimilarRecordsAdapter($channel = null)
121
- {
122
- return $this->_getAdapter("similarRecords", $channel);
123
- }
124
-
125
- public function getTrackingAdapter($channel = null)
126
- {
127
- return $this->_getAdapter("tracking", $channel);
128
- }
129
-
130
- public function getLegacyTrackingAdapter($channel = null)
131
- {
132
- return $this->_getAdapter("legacyTracking", $channel);
133
- }
134
-
135
- public function configureSearchAdapter($params, $channel = null, $id = null)
136
- {
137
- $this->_configureAdapter($params, "search", $channel, $id);
138
- }
139
-
140
- public function configureScicAdapter($params, $channel = null, $id = null)
141
- {
142
- $this->_configureAdapter($params, "scic", $channel, $id);
143
- }
144
-
145
- public function configureSuggestAdapter($params, $channel = null, $id = null)
146
- {
147
- $this->_configureAdapter($params, "suggest", $channel, $id);
148
- }
149
-
150
- public function configureRecommendationAdapter($params, $channel = null, $id = null)
151
- {
152
- $this->_configureAdapter($params, "recommendation", $channel, $id);
153
- }
154
-
155
- public function configureTagCloudAdapter($params, $channel = null, $id = null)
156
- {
157
- $this->_configureAdapter($params, "tagCloud", $channel, $id);
158
- }
159
-
160
- public function configureCompareAdapter($params, $channel = null, $id = null)
161
- {
162
- $this->_configureAdapter($params, "compare", $channel, $id);
163
- }
164
-
165
- public function configureImportAdapter($params, $channel = null, $id = null)
166
- {
167
- $this->_configureAdapter($params, "import", $channel, $id);
168
- }
169
-
170
- public function configureProductCampaignAdapter($params, $channel = null, $id = null)
171
- {
172
- $this->_configureAdapter($params, "productCampaign", $channel, $id);
173
- }
174
-
175
- public function configureSimilarRecordsAdapter($params, $channel = null, $id = null)
176
- {
177
- $this->_configureAdapter($params, "similarRecords", $channel, $id);
178
- }
179
-
180
- public function configureTrackingAdapter($params, $channel = null, $id = null)
181
- {
182
- $this->_configureAdapter($params, "tracking", $channel, $id);
183
- }
184
-
185
- protected function _configureAdapter($params, $type, $channel = null, $id = null)
186
- {
187
- $adapter = $this->_getAdapter($type, $channel, $id);
188
- $adapterId = $this->_getAdapterIdentifier($type, $channel, $id);
189
- $this->_paramHashes[$adapterId] = $this->_createParametersHash($params);
190
-
191
- foreach($params as $key => $value)
192
- $adapter->setParam($key, $value);
193
- }
194
-
195
- /**
196
- * returns the hash that identifies a certain combination of parameters.
197
- * It represents the current parameter state of the adapter specified by $type, $channel and $id
198
- *
199
- * @param $type (any adapter type)
200
- * @param $channel (default: null => default channel)
201
- * @param $id (default: null => no special id)
202
- * @return string
203
- */
204
- protected function _getParametersHash($type, $channel = null, $id = null)
205
- {
206
- $returnValue = '';
207
- $adapterId = $this->_getAdapterIdentifier($type, $channel, $id);
208
- if (array_key_exists($adapterId, $this->_paramHashes))
209
- {
210
- $returnValue = $this->_paramHashes[$adapterId];
211
- }
212
- return $returnValue;
213
- }
214
-
215
- private function _createParametersHash($params)
216
- {
217
- $returnValue = '';
218
- if($params) {
219
- ksort($params);
220
- $returnValue = md5(http_build_query($params));
221
- }
222
- return $returnValue;
223
- }
224
-
225
- /**
226
- * get identifying hash for each adapter based on type, channel and id
227
- * @param $type
228
- * @param $channel (default: null)
229
- * @param $id (default: null)
230
- * @return string hash
231
- */
232
- protected function _getAdapterIdentifier($type, $channel = null, $id = null)
233
- {
234
- $args = func_get_args();
235
- return implode('_', $args);
236
- }
237
-
238
- /**
239
- * @return FACTFinder_Abstract_Adapter
240
- */
241
- protected function _getAdapter($type, $channel = null, $id = null)
242
- {
243
- $format = $this->_getFormat($type);
244
- $hashKey = $this->_getAdapterIdentifier($type, $channel, $id);
245
-
246
- // get the channel after calculating the adapter identifier
247
- if(!$channel)
248
- $channel = $this->_getConfiguration()->getChannel();
249
-
250
- if(!isset($this->_adapters[$hashKey][$channel]))
251
- {
252
- $config = $this->_getConfiguration();
253
- $encodingHandler = FF::getSingleton('encodingHandler', $config);
254
- $dataProvider = $this->_getParallelDataProvider();
255
- $dataProvider->setParam('channel', $channel);
256
-
257
- /*
258
- // new tracking needs session ID and sourceRefKey for every request
259
- // helper must not be used inside this class, as it is also used without the app context
260
- // TODO: do it in a different way
261
- if(!Mage::helper('factfinder')->useOldTracking()) {
262
- $dataProvider->setParam('sourceRefKey', Mage::getSingleton('core/session')->getFactFinderRefKey());
263
- $dataProvider->setParam('sid' , md5(Mage::getSingleton('core/session')->getSessionId()));
264
- }*/
265
-
266
- $this->_adapters[$hashKey][$channel] = FF::getInstance(
267
- $format.'/'.$type.'Adapter',
268
- $dataProvider,
269
- $this->_getParamsParser(),
270
- $encodingHandler,
271
- $this->_logger
272
- );
273
- }
274
- return $this->_adapters[$hashKey][$channel];
275
- }
276
-
277
- protected function _getFormat($type)
278
- {
279
- $format = 'http';
280
- if (!in_array($type, array('scic', 'suggest', 'legacyTracking'))) {
281
- $version = $this->_getConfiguration()->getFactFinderVersion();
282
- $format = 'xml' . $version;
283
- return $format;
284
- }
285
- return $format;
286
- }
287
-
288
- public function configureStatusHelper($channel = null)
289
- {
290
- if(!$channel)
291
- $channel = $this->_getConfiguration()->getChannel();
292
- if(!isset($this->_statusHelpers[$channel]))
293
- {
294
- $config = $this->_getConfiguration();
295
- $encodingHandler = FF::getSingleton('encodingHandler', $config);
296
- $this->_statusHelpers[$channel] = FF::getInstance(
297
- 'http/statusHelper',
298
- $config,
299
- $this->_logger,
300
- $channel
301
- );
302
- }
303
- }
304
-
305
- /**
306
- * @return FACTFinderCustom_Configuration config
307
- */
308
- protected function _getConfiguration($configArray = null)
309
- {
310
- if ($this->_config == null) {
311
- $this->_config = FF::getSingleton('configuration', $configArray);
312
- }
313
- return $this->_config;
314
- }
315
-
316
- public function setConfiguration($configArray)
317
- {
318
- $this->_config = FF::getSingleton('configuration', $configArray);
319
- }
320
-
321
- /**
322
- * @param int $storeId
323
- * @return \Flagbit_FactFinder_Model_Facade
324
- */
325
- public function setStoreId($storeId) {
326
- $this->_getConfiguration()->setStoreId($storeId);
327
-
328
- return $this;
329
- }
330
-
331
- /**
332
- * @return FACTFinder_Abstract_DataProvider
333
- **/
334
- protected function _getParallelDataProvider()
335
- {
336
- $config = $this->_getConfiguration();
337
- $params = $this->_getParamsParser()->getServerRequestParams();
338
- $dp = FACTFinder_Http_ParallelDataProvider::getDataProvider($params, $config, $this->_logger);
339
- return $dp;
340
- }
341
-
342
- /**
343
- * @return FACTFinder_ParametersParser
344
- */
345
- protected function _getParamsParser()
346
- {
347
- if ($this->_paramsParser == null) {
348
- $config = $this->_getConfiguration();
349
- $encodingHandler = FF::getSingleton('encodingHandler', $config);
350
- $this->_paramsParser = FF::getInstance('parametersParser', $config, $encodingHandler);
351
- }
352
- return $this->_paramsParser;
353
- }
354
-
355
- public function getManagementUrl()
356
- {
357
- $urlBuilder = $this->_getUrlBuilder();
358
- $urlBuilder->setAction('Management.ff');
359
- return $urlBuilder->getNonAuthenticationUrl();
360
- }
361
-
362
- public function getSuggestUrl()
363
- {
364
- $urlBuilder = $this->_getUrlBuilder();
365
- $urlBuilder->setAction('Suggest.ff');
366
- $urlBuilder->setParams(array());
367
-
368
- return $urlBuilder->getNonAuthenticationUrl();
369
- }
370
-
371
- protected function _getUrlBuilder()
372
- {
373
- if($this->_urlBuilder === null) {
374
- $config = $this->_getConfiguration();
375
- $params = $this->_getParamsParser()->getServerRequestParams();
376
-
377
- $this->_urlBuilder = FF::getInstance('http/urlBuilder', $params, $config, $this->_logger);
378
- }
379
- return $this->_urlBuilder;
380
- }
381
-
382
- public function applyTracking($channel = null, $id = null)
383
- {
384
- return $this->_getFactFinderObject("tracking", "applyTracking", $channel, $id);
385
- }
386
-
387
- public function applyScicTracking($channel = null, $id = null)
388
- {
389
- return $this->_getFactFinderObject("scic", "applyTracking", $channel, $id);
390
- }
391
-
392
- public function applyLegacyTracking($channel = null, $id = null)
393
- {
394
- return $this->_getFactFinderObject("legacyTracking", "applyTracking", $channel, $id);
395
- }
396
-
397
- public function getAfterSearchNavigation($channel = null, $id = null)
398
- {
399
- return $this->_getFactFinderObject("search", "getAsn", $channel, $id);
400
- }
401
-
402
- public function getCampaigns($channel = null, $id = null)
403
- {
404
- return $this->_getFactFinderObject("search", "getCampaigns", $channel, $id);
405
- }
406
-
407
- public function getProductCampaigns($channel = null, $id = null)
408
- {
409
- return $this->_getFactFinderObject("productCampaign", "getCampaigns", $channel, $id);
410
- }
411
-
412
- public function getRecommendations($channel = null, $id = null)
413
- {
414
- return $this->_getFactFinderObject("recommendation", "getRecommendations", $channel, $id);
415
- }
416
-
417
- public function getSearchError($channel = null, $id = null)
418
- {
419
- return $this->_getFactFinderObject("search", "getError", $channel, $id);
420
- }
421
-
422
- public function getSearchParams($channel = null, $id = null)
423
- {
424
- return $this->_getFactFinderObject("search", "getSearchParams", $channel, $id);
425
- }
426
-
427
- public function getSearchResult($channel = null, $id = null)
428
- {
429
- return $this->_getFactFinderObject("search", "getResult", $channel, $id);
430
- }
431
-
432
- public function getSearchStackTrace($channel = null, $id = null)
433
- {
434
- return $this->_getFactFinderObject("search", "getStackTrace", $channel, $id);
435
- }
436
-
437
- public function getSearchStatus($channel = null, $id = null)
438
- {
439
- return $this->_getFactFinderObject("search", "getStatus", $channel, $id);
440
- }
441
-
442
- public function getSuggestions($channel = null, $id = null)
443
- {
444
- return $this->_getFactFinderObject("suggest", "getSuggestions", $channel, $id);
445
- }
446
-
447
- public function getTagCloud($channel = null, $id = null)
448
- {
449
- return $this->_getFactFinderObject("tagCloud", "getTagCloud", $channel, $id);
450
- }
451
-
452
- protected function _getFactFinderObject($type, $objectGetter, $channel = null, $id = null)
453
- {
454
- $cacheKey = '';
455
- $data = null;
456
-
457
- if ($this->_useSearchCaching() && stripos($type, 'tracking') === false)
458
- {
459
- $adapterId = $this->_getAdapterIdentifier($type, $channel, $id);
460
- $cacheKey = 'FACTFINDER_'.$adapterId . '_' . $objectGetter .'_'. $this->_getParametersHash($type, $channel, $id);
461
- if($cache = Mage::app()->loadCache($cacheKey))
462
- {
463
- $data = unserialize($cache);
464
- }
465
- }
466
-
467
- if ($data == null) {
468
- try {
469
- $this->_loadAllData();
470
-
471
- // BUG Potential:
472
- // if you read this because you got the error message, that you must call
473
- // > 'loadAllData' before trying to get data! <
474
- // this might have happened because you initialized another adapter and not the one
475
- // that is called here
476
- $adapter = $this->_getAdapter($type, $channel, $id);
477
- $data = $adapter->$objectGetter();
478
-
479
- if($this->_useSearchCaching())
480
- {
481
- Mage::app()->saveCache(serialize($data), $cacheKey, array('FACTFINDER_SEARCH'), 600);
482
- }
483
-
484
- } catch (Exception $e) {
485
- Mage::logException($e);
486
- }
487
- }
488
- return $data;
489
- }
490
-
491
- public function getActualFactFinderVersion()
492
- {
493
- try {
494
- $channel = $this->_getConfiguration()->getChannel();
495
- $this->_loadAllData();
496
- return $this->_statusHelpers[$channel]->getVersionNumber();
497
- } catch (Exception $e) {
498
- Mage::logException($e);
499
- return null;
500
- }
501
- }
502
-
503
- private function _useSearchCaching()
504
- {
505
- if ($this->_useCaching == null)
506
- {
507
- // caching only works from version 5.3 because of php bug 45706 (http://bugs.php.net/45706):
508
- // because of it, the asn objects can't be serialized and cached
509
- // this bug was fixed with 5.3.0 (http://www.php.net/ChangeLog-5.php)
510
- $this->_useCaching = (version_compare(PHP_VERSION, '5.3.0') >= 0 && Mage::app()->useCache('factfinder_search'));
511
- }
512
- return $this->_useCaching;
513
- }
514
-
515
- public function getActualFactFinderVersionString()
516
- {
517
- try {
518
- $channel = $this->_getConfiguration()->getChannel();
519
- $this->_loadAllData();
520
- return $this->_statusHelpers[$channel]->getVersionString();
521
- } catch (Exception $e) {
522
- Mage::logException($e);
523
- return null;
524
- }
525
- }
526
-
527
- public function getFactFinderStatus($channel = null)
528
- {
529
- try {
530
- if(!$channel)
531
- $channel = $this->_getConfiguration()->getChannel();
532
- $this->_loadAllData();
533
- return $this->_statusHelpers[$channel]->getStatusCode();
534
- } catch (Exception $e) {
535
- Mage::logException($e);
536
- return null;
537
- }
538
- }
539
-
540
- protected function _loadAllData()
541
- {
542
- FACTFinder_Http_ParallelDataProvider::loadAllData();
543
- }
544
-
545
- public function getRequestParams()
546
- {
547
- return $this->_getParamsParser()->getRequestParams();
548
- }
549
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Abstract.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- /**
3
- * Abstract class for Fact Finder object handlers
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: Abstract.php 13.09.12 14:19 $
10
- *
11
- **/
12
- abstract class Flagbit_FactFinder_Model_Handler_Abstract
13
- {
14
- /**
15
- * @var Flagbit_FactFinder_Model_Facade
16
- **/
17
- protected $_facade;
18
-
19
- /**
20
- *
21
- */
22
- public function __construct()
23
- {
24
- $this->configureFacade();
25
- }
26
-
27
- /**
28
- * Implement this method to set up any adapters the handler will need later on.
29
- * WARNING: You will always have to configure...() the adapter once, even if you do not set any parameters.
30
- * This will register the adapter with the Facade and lets it query all data in parallel.
31
- */
32
- abstract protected function configureFacade();
33
-
34
- /**
35
- * @return Flagbit_FactFinder_Model_Facade
36
- */
37
- protected function _getFacade()
38
- {
39
- if($this->_facade === null)
40
- {
41
- $this->_facade = Mage::getSingleton('factfinder/facade');
42
- }
43
- return $this->_facade;
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/CheckStatus.php DELETED
@@ -1,150 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- require_once BP.DS.'lib'.DS.'FACTFinder'.DS.'Loader.php';
11
-
12
- /**
13
- * Checks whether the configuration is working
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Martin Buettner <martin.buettner@omikron.net>
19
- * @version $Id: CheckStatus.php 17.09.12 15:00 $
20
- *
21
- **/
22
- class Flagbit_FactFinder_Model_Handler_CheckStatus
23
- extends Flagbit_FactFinder_Model_Handler_Abstract
24
- {
25
- protected $_configArray;
26
-
27
- protected $_errorMessages = array();
28
-
29
- protected $_helper;
30
-
31
- protected $_secondaryChannels;
32
-
33
- public function __construct($configArray = null)
34
- {
35
- $this->_configArray = $configArray;
36
- parent::__construct();
37
- }
38
-
39
- protected function configureFacade()
40
- {
41
- FF::getSingleton('configuration', $this->_configArray);
42
- $this->_getFacade()->configureStatusHelper();
43
-
44
- $this->_secondaryChannels = FF::getSingleton('configuration')->getSecondaryChannels();
45
- foreach($this->_secondaryChannels AS $channel)
46
- $this->_getFacade()->configureStatusHelper($channel);
47
-
48
- }
49
-
50
- public function checkStatus($configuredVersion)
51
- {
52
- // uncomment to see debug output
53
- //ob_start();
54
-
55
- $statusOkay = true;
56
- $this->_errorMessage = array();
57
-
58
- $primaryStatus = $this->_getFacade()->getFactFinderStatus();
59
- if($primaryStatus !== FFE_OK)
60
- {
61
- $this->_errorMessages[] = $this->_retrieveErrorMessage($primaryStatus);
62
- $statusOkay = false;
63
- }
64
- foreach($this->_secondaryChannels AS $channel)
65
- {
66
- $secondaryStatus = $this->_getFacade()->getFactFinderStatus($channel);
67
- if($secondaryStatus !== FFE_OK)
68
- {
69
- $this->_errorMessages[] = $this->_retrieveErrorMessage($secondaryStatus, $channel);
70
- $statusOkay = false;
71
- }
72
- }
73
-
74
- $actualVersion = $this->_getFacade()->getActualFactFinderVersion();
75
- $actualVersionString = $this->_getFacade()->getActualFactFinderVersionString();
76
-
77
- if($statusOkay && intval($actualVersion) != 1 && $actualVersion < $configuredVersion)
78
- {
79
- $this->_errorMessages[] = $this->_getHelper()->__(
80
- 'The configured FACT-Finder version is higher than the actual version of your FACT-Finder. '.
81
- 'Consider upgrading your FACT-Finder, or reduce the configured version to '
82
- ).$actualVersionString;
83
- $statusOkay = false;
84
- }
85
-
86
- // uncomment to see debug output
87
- //$this->_errorMessages[] = ob_get_clean();
88
-
89
- return $statusOkay;
90
- }
91
-
92
- protected function _retrieveErrorMessage($statusCode, $channel = null)
93
- {
94
- $helper = $this->_getHelper();
95
- if($channel === null)
96
- $errorMessage = $helper->__('Error in Primary Channel') . ': ';
97
- else
98
- $errorMessage = $helper->__('Error in Channel').' "'.$channel.'": ';
99
-
100
- switch($statusCode)
101
- {
102
- case FFE_WRONG_CONTEXT:
103
- $errorMessage .= $helper->__('FACT-Finder not found on server. Please check your context setting.');
104
- return $errorMessage;
105
- case FFE_CHANNEL_DOES_NOT_EXIST:
106
- $errorMessage .= $helper->__('Channel does not exist or the specified user does not have sufficient rights.');
107
- return $errorMessage;
108
- case FFE_WRONG_CREDENTIALS:
109
- $errorMessage .= $helper->__('Could not log into FACT-Finder with the given settings. Please check username, password, prefix and postfix.');
110
- return $errorMessage;
111
- case FFE_SERVER_TIME_MISMATCH:
112
- $errorMessage .= $helper->__('Your server\'s clock does not agree with FACT-Finder\'s. Please make sure your clock is set correctly.');
113
- return $errorMessage;
114
- }
115
-
116
- $codeType = floor($statusCode / 1000) * 1000;
117
-
118
- switch($codeType)
119
- {
120
- case FFE_CURL_ERROR:
121
- $errorMessage .= $helper->__('Could not establish HTTP connection.');
122
- $errorMessage .= ' cURL Error Code: '.($statusCode - $codeType);
123
- break;
124
- case FFE_HTTP_ERROR:
125
- $errorMessage .= $helper->__('Could not contact FACT-Finder.');
126
- $errorMessage .= ' HTTP Status Code: '.($statusCode - $codeType);
127
- break;
128
- case FFE_FACT_FINDER_ERROR:
129
- $errorMessage .= $helper->__('There is a problem with FACT-Finder. Please contact FACT-Finder Support.');
130
- break;
131
- default:
132
- $errorMessage .= $helper->__('An unknown error has occurred. Please contact FACT-Finder Support.');
133
- break;
134
- }
135
-
136
- return $errorMessage;
137
- }
138
-
139
- protected function _getHelper()
140
- {
141
- if($this->_helper === null)
142
- $this->_helper = Mage::helper('factfinder');
143
- return $this->_helper;
144
- }
145
-
146
- public function getErrorMessages()
147
- {
148
- return $this->_errorMessages;
149
- }
150
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/ProductCampaign.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- /**
3
- * Handles product campaign data
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: ProductCampaign.php 14.09.12 08:42 $
10
- *
11
- **/
12
- abstract class Flagbit_FactFinder_Model_Handler_ProductCampaign
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected $_productIds = array();
16
-
17
- protected $_campaigns;
18
-
19
- protected $_featureAvailable = true;
20
-
21
- public function __construct($productIds)
22
- {
23
- $this->_productIds = $productIds;
24
- parent::__construct();
25
- }
26
-
27
- /**
28
- * {@inheritdoc}
29
- */
30
- protected function configureFacade()
31
- {
32
- $params = array();
33
- $params['do'] = $this->_getDoParam();
34
- $params['productNumber'] = $this->_getProductNumberParam();
35
- $params['idsOnly'] = 'true';
36
-
37
- try {
38
- $adapter = $this->_getFacade()->configureProductCampaignAdapter($params);
39
- } catch(Exception $e) {
40
- Mage::helper('factfinder/debug')->log('Product Campaigns not available before FACT-Finder 6.7.');
41
- $this->_featureAvailable = false;
42
- return;
43
- }
44
- }
45
-
46
- abstract protected function _getDoParam();
47
- abstract protected function _getProductNumberParam();
48
-
49
- public function getActiveAdvisorQuestions()
50
- {
51
- $campaigns = $this->getCampaigns();
52
-
53
- $questions = array();
54
-
55
- if($campaigns && $campaigns->hasActiveQuestions()){
56
- $questions = $campaigns->getActiveQuestions();
57
- }
58
-
59
- return $questions;
60
- }
61
-
62
- public function getCampaigns()
63
- {
64
- if(!$this->_featureAvailable)
65
- $this->_campaigns = array();
66
-
67
- if($this->_campaigns === null)
68
- {
69
- $this->_campaigns = $this->_getFacade()->getProductCampaigns();
70
- if ($this->_campaigns === null)
71
- $this->_campaigns = array();
72
- }
73
- return $this->_campaigns;
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/ProductDetailCampaign.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * Handles product campaign data on product detail pages
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: ProductCampaign.php 14.09.12 08:42 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_ProductDetailCampaign
13
- extends Flagbit_FactFinder_Model_Handler_ProductCampaign
14
- {
15
- protected function _getDoParam()
16
- {
17
- return 'getProductCampaigns';
18
- }
19
-
20
- protected function _getProductNumberParam()
21
- {
22
- if(is_array($this->_productIds))
23
- return current($this->_productIds);
24
- else
25
- return $this->_productIds;
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Recommendations.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
- /**
3
- * Handles product campaign data
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: Recommendations.php 14.09.12 11:53 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_Recommendations
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected $_productIds = array();
16
-
17
- protected $_recommendations;
18
-
19
- public function __construct($productIds)
20
- {
21
- $this->_productIds = $productIds;
22
- parent::__construct();
23
- }
24
-
25
- protected function configureFacade()
26
- {
27
- $params = array();
28
- $params['idsOnly'] = 'true';
29
- $params['id'] = $this->_getIdParam();
30
- $this->_getFacade()->configureRecommendationAdapter($params);
31
- }
32
-
33
- public function getRecommendations()
34
- {
35
- if($this->_recommendations === null)
36
- {
37
- $this->_recommendations = $this->_getFacade()->getRecommendations();
38
- if ($this->_recommendations === null)
39
- $this->_recommendations = array();
40
- }
41
- return $this->_recommendations;
42
- }
43
-
44
- protected function _getIdParam()
45
- {
46
- if(is_array($this->_productIds))
47
- return $this->_productIds;
48
- else
49
- return array($this->_productIds);
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Search.php DELETED
@@ -1,435 +0,0 @@
1
- <?php
2
- /**
3
- * Handles Search data for secondary channels
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: Search.php 17.09.12 11:50 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_Search
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected $_currentFactFinderCategoryPath;
16
-
17
- protected $_searchResult;
18
- protected $_searchResultCount;
19
- protected $_campaigns;
20
- protected $_afterSearchNavigation;
21
-
22
- protected function configureFacade()
23
- {
24
- $params = $this->_collectParams();
25
-
26
- $this->_getFacade()->configureSearchAdapter($params);
27
- }
28
-
29
- /**
30
- * prepares all request parameters for the primary search adapter
31
- **/
32
-
33
- protected function _collectParams()
34
- {
35
- // search Helper
36
- $helper = Mage::helper('factfinder/search');
37
- $_request = Mage::app()->getRequest();
38
- $requestParams = $this->_getFacade()->getRequestParams();
39
- $params = array();
40
-
41
- if (strpos(Mage::getStoreConfig('factfinder/config/internal_ip'), Mage::helper('core/http')->getRemoteAddr()) !== false) {
42
- $params['log'] = 'internal';
43
- }
44
-
45
- switch($_request->getModuleName()) {
46
-
47
- case "xmlconnect":
48
- $_query = $helper->getQueryText();
49
- $params['idsOnly'] = FF::getSingleton('configuration')->getIdsOnly() ? 'true' : 'false';
50
- $params['query'] = $_query;
51
-
52
- $count = isset($requestParams['count']) ? $requestParams['count'] : 0;
53
- if ($count > 0) {
54
- $params['productsPerPage'] = $count;
55
- $params['page'] = ($requestParams['offset'] / $count) + 1;
56
- }
57
-
58
- // add Sorting Param
59
- foreach($requestParams as $key => $value){
60
- if(substr($key, 0, 6) == 'order_') {
61
- $key = substr($key, 6);
62
- if(!in_array($key, array('position', 'relevance'))) {
63
- $params['sort'.$key] = $value;
64
- }
65
- }
66
- }
67
-
68
- // add Filter Params
69
- foreach($requestParams as $key => $value){
70
- $value = base64_decode($value);
71
- if(strpos($value, '|')) {
72
- $param = explode('|', $value);
73
- if($key == 'Category' || $key == 'category') {
74
- $categories = array_merge(array_slice(explode('/', $param[0]), 1), array($param[1]));
75
- foreach($categories AS $k => $v) { $categories[$k] = urldecode($v); }
76
- $filterKey = '';
77
- foreach($categories as $category){
78
- $category = str_replace('%2F', '/', str_replace('%2B', '+', $category));
79
- $params['filtercategoryROOT'.$filterKey] = $category;
80
- $filterKey .= '/'.str_replace('+', '%2B', str_replace('/', '%2F', $category));
81
- }
82
- } else {
83
- $params['filter'.$param[0]] = $param[1];
84
- }
85
- }
86
- }
87
-
88
- break;
89
-
90
- case "catalog":
91
- if (!isset($requestParams['Category']) && !isset($requestParams['category'])) {
92
- $requestParams['Category'] = $this->_getCurrentFactFinderCategoryPath();
93
- }
94
-
95
-
96
- $params['navigation'] = 'true';
97
-
98
- case "catalogsearch":
99
- default:
100
- $_query = '*';
101
- if ($_request->getModuleName() == 'catalogsearch') {
102
- $_query = $helper->getQueryText();
103
- }
104
-
105
- // add Default Params
106
- $params['idsOnly'] = FF::getSingleton('configuration')->getIdsOnly() ? 'true' : 'false';
107
- $params['productsPerPage'] = $helper->getPageLimit();
108
- $params['query'] = $_query;
109
- $params['page'] = $helper->getCurrentPage();
110
-
111
- // add Sorting Param, but only if it was set explicitly via url
112
- foreach($requestParams as $key => $value) {
113
- if($key == 'order'
114
- && $helper->getCurrentOrder()
115
- && $helper->getCurrentDirection()
116
- && $helper->getCurrentOrder() != 'position'
117
- && $helper->getCurrentOrder() != 'relevance')
118
- {
119
- $params['sort'.$helper->getCurrentOrder()] = $helper->getCurrentDirection();
120
- }
121
- }
122
-
123
- // add Filter Params
124
- foreach($requestParams as $key => $value) {
125
- if(strpos($value, '|')) {
126
- $param = explode('|', $value);
127
- switch($param[1]) {
128
-
129
- case 'slider':
130
- $subParam = explode(':', $param[2]);
131
- $params[$subParam[0]] = $subParam[1];
132
- $subParam = explode(':', $param[3]);
133
- $params[$subParam[0]] = $subParam[1];
134
- break;
135
-
136
- default:
137
- if($key == 'Category' || $key == 'category') {
138
- $categories = array_merge(array_slice(explode('/', $param[0]), 1), array($param[1]));
139
- foreach($categories AS $k => $v) { $categories[$k] = $v; }
140
- $filterKey = '';
141
- foreach($categories as $category) {
142
- $category = str_replace('%2F', '/', str_replace('%2B', '+', $category));
143
- $params['filtercategoryROOT'.$filterKey] = $category;
144
- $filterKey .= '/'.str_replace('+', '%2B', str_replace('/', '%2F', $category));
145
- }
146
-
147
- } else {
148
- $params['filter'.$param[0]] = $param[1];
149
- }
150
- break;
151
- }
152
- }
153
- }
154
- break;
155
-
156
- }
157
-
158
- return $params;
159
- }
160
-
161
- protected function _getCurrentFactFinderCategoryPath($all = false)
162
- {
163
- $returnValue = array();
164
- if($this->_currentFactFinderCategoryPath == null){
165
- $this->_currentFactFinderCategoryPath = array();
166
- if (Mage::getStoreConfigFlag('factfinder/activation/navigation') && Mage::registry('current_category')){
167
- $this->_currentFactFinderCategoryPath = array();
168
- /* @var $category Mage_Catalog_Model_Category */
169
- $category = Mage::registry('current_category');
170
-
171
- $pathInStore = $category->getPathInStore();
172
- $pathIds = array_reverse(explode(',', $pathInStore));
173
-
174
- $categories = $category->getParentCategories();
175
- $mainCategoriesString = '';
176
- foreach ($pathIds as $categoryId) {
177
- if (isset($categories[$categoryId]) && $categories[$categoryId]->getName()) {
178
- if(empty($mainCategoriesString)){
179
- $this->_currentFactFinderCategoryPath[] = 'categoryROOT|'.$categories[$categoryId]->getName();
180
- }else{
181
- $this->_currentFactFinderCategoryPath[] = 'categoryROOT'.$mainCategoriesString.'|'.$categories[$categoryId]->getName();
182
- }
183
- $mainCategoriesString .= '/'. str_replace('/', '%2F', $categories[$categoryId]->getName());
184
- }
185
- }
186
- }
187
- }
188
-
189
- if($all === false){
190
- if (isset($this->_currentFactFinderCategoryPath[count($this->_currentFactFinderCategoryPath)-1])) {
191
- $returnValue = $this->_currentFactFinderCategoryPath[count($this->_currentFactFinderCategoryPath)-1];
192
- }
193
- else {
194
- $returnValue = false;
195
- }
196
- } else {
197
- $returnValue = $this->_currentFactFinderCategoryPath;
198
- }
199
-
200
- return $returnValue;
201
- }
202
-
203
- public function getAfterSearchNavigation()
204
- {
205
- if($this->_afterSearchNavigation == null) {
206
- $this->_afterSearchNavigation = array();
207
-
208
- $result = $this->_getFacade()->getAfterSearchNavigation();
209
-
210
- if ($result instanceof FACTFinder_Asn
211
- && count($result)) {
212
-
213
- foreach ($result as $row) {
214
- $this->_afterSearchNavigation[] = array(
215
- 'attribute_code' => $row->getName(),
216
- 'name' => $row->getName(),
217
- 'unit' => $row->getUnit(),
218
- 'items' => $this->_getAttributeOptions($row->getArrayCopy(), $row->getUnit()),
219
- 'count' => $row->count(),
220
- 'type' => $this->_getFilterType($row->getArrayCopy()),
221
- 'store_label' => $row->getName()
222
- );
223
- }
224
- }
225
- }
226
- return $this->_afterSearchNavigation;
227
- }
228
-
229
- /**
230
- * get Filter Type by FACT-Finder FilterItem
231
- *
232
- * @param array $options
233
- * @return string
234
- */
235
- protected function _getFilterType($options)
236
- {
237
- $defaultType = 'item';
238
- foreach($options as $option){
239
- if(!$option->getType()){
240
- continue;
241
- }
242
- $defaultType = $option->getType();
243
- break;
244
- }
245
- return $defaultType;
246
- }
247
-
248
- /**
249
- * get Attribute Options Array from FactFinder FilterGroupItems
250
- *
251
- * @param FACTFinder_AsnFilterItem $options
252
- * @param string $unit
253
- * @return array
254
- */
255
- protected function _getAttributeOptions($options, $unit = '')
256
- {
257
- $attributeOption = array();
258
- if (!empty($unit)) $unit = ' ' . $unit;
259
- $_currentCategoryPath = $this->_getCurrentFactfinderCategoryPath(true);
260
- $helper = Mage::helper('factfinder/search');
261
- foreach($options as $option){
262
-
263
- switch ($option->getType()){
264
-
265
- case "slider":
266
- $attributeOption[] = array(
267
- 'type' => $option->getType(),
268
- 'label' => 'slider',
269
- 'value' => $this->_getAttributeOptionValue($option),
270
- 'absolute_min' => $option->getAbsoluteMin(),
271
- 'absolute_max' => $option->getAbsoluteMax(),
272
- 'selected_min' => $option->getSelectedMin(),
273
- 'selected_max' => $option->getSelectedMax(),
274
- 'count' => true,
275
- 'selected' => false //$option->isSelected()
276
- );
277
- break;
278
-
279
- default:
280
- if (!Mage::helper('core/string')->strlen($option->getValue())) {
281
- continue;
282
- }
283
- // remove Categories from top Level Navigation
284
- $_value = $this->_getAttributeOptionValue($option);
285
- if(Mage::getStoreConfigFlag('factfinder/activation/navigation')
286
- && !$helper->getIsOnSearchPage()
287
- && strpos($option->getField(), 'categoryROOT') !== FALSE
288
- && (
289
- empty($_value) === true
290
- || in_array($_value, $_currentCategoryPath)
291
- && $_currentCategoryPath[count($_currentCategoryPath)-1] != $_value
292
- )){
293
- continue;
294
- }
295
-
296
- $attributeOption[] = array(
297
- 'type' => 'attribute',
298
- 'label' => $option->getValue() . $unit,
299
- 'value' => $_value,
300
- 'count' => $option->getMatchCount(),
301
- 'selected' => $option->isSelected(),
302
- 'clusterLevel' => $option->getClusterLevel()
303
- );
304
- break;
305
- }
306
- }
307
- return $attributeOption;
308
- }
309
-
310
- /**
311
- * get Attribute option Value
312
- *
313
- * @param string $option
314
- * @return string
315
- */
316
- protected function _getAttributeOptionValue($option)
317
- {
318
- $searchParams = $this->_getFacade()->getSearchParams();
319
- if($searchParams instanceof FACTFinder_Parameters)
320
- $selectOptions = $searchParams->getFilters();
321
-
322
- $value = null;
323
- switch ($option->getType()) {
324
-
325
- // handle Slider Attributes
326
- case "slider":
327
- $value = $option->getField().'|'.$option->getType().'|'.str_replace(array('&', '='), array('|', ':'), $option->getValue()).'[VALUE]';
328
- break;
329
-
330
- // handle default Attributes
331
- default:
332
- $value = $option->getField();
333
- if($option->isSelected()) {
334
-
335
- // handle multi-selectable Attributes
336
- if(isset($selectOptions[$option->getField()]) ){
337
- if(strpos($option->getField(), 'categoryROOT') === false) {
338
- $values = explode('~~~', $selectOptions[$option->getField()]);
339
- unset($values[array_search($option->getValue(), $values)]);
340
- $value .= '|'.implode('~~~', $values);
341
-
342
- } else {
343
- $values = explode('/',str_replace('|'.$selectOptions[$option->getField()], '', $value));
344
- $valueCount = count($values);
345
- $value = '';
346
- if($valueCount > 1) {
347
- for($i=0 ; $valueCount > $i ; $i++) {
348
- $value .= ($i != 0 ? ($i == $valueCount-1 ? '|' : '/') : '').$values[$i];
349
- }
350
- }
351
- }
352
- }
353
- } else {
354
- $value .= '|'.$option->getValue();
355
- // handle multi-selectable Attributes
356
- if(isset($selectOptions[$option->getField()])) {
357
- $value .= '~~~'.$selectOptions[$option->getField()];
358
- }
359
- }
360
-
361
- // Workaround if only one option is selected
362
- if($value == $option->getField().'|') {
363
- $value = '';
364
- }
365
-
366
- break;
367
- }
368
- return $value;
369
- }
370
-
371
- public function getRedirect()
372
- {
373
- $url = null;
374
- $campaigns = $this->getCampaigns();
375
-
376
- if (!empty($campaigns) && $campaigns->hasRedirect()) {
377
- $url = $campaigns->getRedirectUrl();
378
- }
379
- return $url;
380
- }
381
-
382
- public function getCampaigns()
383
- {
384
- if($this->_campaigns === null)
385
- {
386
- $this->_campaigns = $this->_getFacade()->getCampaigns();
387
- }
388
- return $this->_campaigns;
389
- }
390
-
391
- public function getSearchResultCount()
392
- {
393
- if($this->_searchResultCount === null)
394
- {
395
- $result = $this->_getFacade()->getSearchResult();
396
- if($result instanceof FACTFinder_Result)
397
- $this->_searchResultCount = $result->getFoundRecordsCount();
398
- if($this->_searchResultCount === null)
399
- $this->_searchResultCount = 0;
400
- }
401
- return $this->_searchResultCount;
402
- }
403
-
404
- public function getSearchResult()
405
- {
406
- if($this->_searchResult === null) {
407
- $result = $this->_getFacade()->getSearchResult();
408
- $error = $this->_getFacade()->getSearchError();
409
- if($result === null || $error)
410
- {
411
- Mage::helper('factfinder/search')->registerFailedAttempt();
412
- Mage::logException(new Exception($error));
413
- }
414
- $this->_searchResult = array();
415
- if($result instanceof FACTFinder_Result) {
416
- foreach ($result AS $record){
417
- if(isset($this->_searchResult[$record->getId()])) {
418
- continue;
419
- }
420
- $this->_searchResult[$record->getId()] = new Varien_Object(
421
- array(
422
- 'similarity' => $record->getSimilarity(),
423
- 'position' => $record->getPosition(),
424
- 'original_position' => $record->getOriginalPosition()
425
- )
426
- );
427
- }
428
- }
429
- }
430
-
431
- return $this->_searchResult;
432
- }
433
-
434
-
435
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/SecondarySearch.php DELETED
@@ -1,94 +0,0 @@
1
- <?php
2
- /**
3
- * Handles Search data for secondary channels
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: SecondarySearch.php 17.09.12 11:02 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_SecondarySearch
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected $_secondaryChannels;
16
- protected $_secondarySearchResults = array();
17
-
18
- protected function configureFacade()
19
- {
20
- $params = array();
21
- $params['query'] = Mage::helper('factfinder/search')->getQueryText();
22
- $this->_secondaryChannels = FF::getSingleton('configuration')->getSecondaryChannels();
23
-
24
- foreach($this->_secondaryChannels AS $channel)
25
- {
26
- $params['channel'] = $channel;
27
- $this->_getFacade()->configureSearchAdapter($params, $channel);
28
- }
29
- }
30
-
31
- /**
32
- * returns the FACTFinder_Result object of the given channel.
33
- *
34
- * @param $channel
35
- * @return FACTFinder_Result
36
- */
37
- public function getSecondarySearchResult($channel)
38
- {
39
- if(!$this->isSecondaryChannel($channel))
40
- {
41
- return array();
42
- }
43
-
44
- if(!isset($this->_secondarySearchResults[$channel]))
45
- {
46
- $this->_secondarySearchResults[$channel] = $this->_getFacade()->getSearchResult($channel);
47
- }
48
-
49
- return $this->_secondarySearchResults[$channel];
50
- }
51
-
52
- /**
53
- * returns the search adapter of the FACT-Finder library the module is based on. This adapter gives access to all
54
- * search result relevant objects of the channel's result.
55
- *
56
- * if there is no adapter for that channel, an error is logged an null is returned.
57
- *
58
- * @param $channel
59
- * @return FACTFinder_Default_SearchAdapter (or one of the version specific implementations)
60
- */
61
- public function getSecondarySearchAdapter($channel)
62
- {
63
- echo "$channel <br>";
64
- print_r($this->isSecondaryChannel($channel));
65
- if(!$this->isSecondaryChannel($channel))
66
- {
67
- return null;
68
- }
69
-
70
- if(!isset($this->_secondarySearchAdapters[$channel]))
71
- {
72
- $this->_secondarySearchAdapters[$channel] = $this->_getFacade()->getSearchAdapter($channel);
73
- }
74
-
75
- return $this->_secondarySearchAdapters[$channel];
76
- }
77
-
78
- /**
79
- * returns true if the set channel is a secondary channel. if it is not, it also logs an error
80
- *
81
- * @param $channel
82
- * @return bool
83
- */
84
- private function isSecondaryChannel($channel)
85
- {
86
- if(!in_array($channel, $this->_secondaryChannels))
87
- {
88
- Mage::logException(new Exception("Tried to query a channel that was not configured as a secondary channel."));
89
- return false;
90
- } else {
91
- return true;
92
- }
93
- }
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/ShoppingCartCampaign.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * Handles product campaign data on shopping cart page
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: ProductCampaign.php 14.09.12 08:42 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_ShoppingCartCampaign
13
- extends Flagbit_FactFinder_Model_Handler_ProductCampaign
14
- {
15
- protected function _getDoParam()
16
- {
17
- return 'getShoppingCartCampaigns';
18
- }
19
-
20
- protected function _getProductNumberParam()
21
- {
22
- if(is_array($this->_productIds))
23
- return $this->_productIds;
24
- else
25
- return array($this->_productIds);
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Suggest.php DELETED
@@ -1,106 +0,0 @@
1
- <?php
2
- /**
3
- * Handles Suggest data
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: Suggest.php 17.09.12 08:58 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_Suggest
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected $_query;
16
- protected $_jqueryCallback;
17
- protected $_suggestResult;
18
- protected $_suggestResultAsArray;
19
-
20
- protected $_primaryChannel;
21
- protected $_secondaryChannels;
22
-
23
- /**
24
- * We might need to supply the facade manually, because we might not have a full Magento
25
- * context and we cannot call Mage::getSingleton().
26
- */
27
- public function __construct($query, $jqueryCallback = '', $facade = null)
28
- {
29
- $this->_facade = $facade;
30
- $this->_query = $query;
31
- $this->_jqueryCallback = $jqueryCallback;
32
- parent::__construct();
33
- }
34
-
35
- /**
36
- * {@inheritdoc}
37
- */
38
- protected function configureFacade()
39
- {
40
- $params = array();
41
- $params['format'] = 'json';
42
- $params['query'] = $this->_query;
43
-
44
- $this->_primaryChannel = FF::getSingleton('configuration')->getChannel();
45
- $this->_secondaryChannels = FF::getSingleton('configuration')->getSecondaryChannels();
46
-
47
- $this->_getFacade()->configureSuggestAdapter($params);
48
- foreach($this->_secondaryChannels AS $channel)
49
- $this->_getFacade()->configureSuggestAdapter($params, $channel);
50
-
51
- }
52
-
53
- public function getSuggestions()
54
- {
55
- if($this->_suggestResult === null)
56
- {
57
- $this->_suggestResult = $this->_assembleSuggestResult();
58
- }
59
- return $this->_suggestResult;
60
- }
61
-
62
- public function getSuggestionsAsArray()
63
- {
64
- if($this->_suggestResultAsArray === null)
65
- {
66
- $this->_suggestResultAsArray = $this->_assembleSuggestResultAsArray();
67
- }
68
- return $this->_suggestResultAsArray;
69
- }
70
-
71
- protected function _assembleSuggestResult()
72
- {
73
- // Retrieve and merge all suggestions
74
- // Add a new "channel" field in the process
75
-
76
- $suggestResult = Zend_Json_Decoder::decode($this->_getAndSanitizeSuggestions());
77
- foreach($suggestResult as &$item)
78
- $item["channel"] = $this->_primaryChannel;
79
-
80
- foreach($this->_secondaryChannels AS $channel)
81
- {
82
- $result = Zend_Json_Decoder::decode($this->_getAndSanitizeSuggestions($channel));
83
- foreach($result as &$item)
84
- $item["channel"] = $channel;
85
-
86
- $suggestResult = array_merge($suggestResult, $result);
87
- }
88
-
89
- return $this->_jqueryCallback.'('.Zend_Json_Encoder::encode($suggestResult).');';
90
- }
91
-
92
- protected function _assembleSuggestResultAsArray()
93
- {
94
- // TODO: Multiple channels
95
- return Zend_Json_Decoder::decode($this->_getAndSanitizeSuggestions());
96
- }
97
-
98
- protected function _getAndSanitizeSuggestions($channel = null)
99
- {
100
- $result = $this->_getFacade()->getSuggestions($channel);
101
- if($result === null)
102
- $result = '';
103
-
104
- return $result;
105
- }
106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/TagCloud.php DELETED
@@ -1,71 +0,0 @@
1
- <?php
2
- /**
3
- * Handles TagCloud data
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Martin Buettner <martin.buettner@omikron.net>
9
- * @version $Id: TagCloud.php 13.09.12 14:10 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_TagCloud
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- /**
16
- * @var array
17
- */
18
- protected $_tagCloud;
19
-
20
- /**
21
- * {@inheritdoc}
22
- */
23
- protected function configureFacade()
24
- {
25
- // Registering the needed tag cloud adapter
26
- $this->_getFacade()->configureTagCloudAdapter();
27
- }
28
-
29
- /**
30
- * @return array
31
- */
32
- public function getTerms()
33
- {
34
- $tagCloud = $this->_getTagCloud();
35
-
36
- $terms = array();
37
- foreach ($tagCloud as $item) {
38
- $terms[] = new Varien_Object($this->assembleTermArray($item));
39
- }
40
-
41
- return $terms;
42
- }
43
-
44
- /**
45
- * @param FACTFinder_TagQuery $item
46
- * @return array
47
- */
48
- protected function assembleTermArray($item)
49
- {
50
- $termArray = array();
51
- $termArray['name'] = $item->getValue();
52
- $termArray['url'] = $item->getUrl();
53
- $termArray['popularity'] = $item->getWeight();
54
- $termArray['ratio'] = $item->getWeight();
55
- return $termArray;
56
- }
57
-
58
- /**
59
- * @return array of FACTFinder_TagQuery
60
- */
61
- protected function _getTagCloud()
62
- {
63
- if($this->_tagCloud === null)
64
- {
65
- $this->_tagCloud = $this->_getFacade()->getTagCloud();
66
- if ($this->_tagCloud === null)
67
- $this->_tagCloud = array();
68
- }
69
- return $this->_tagCloud;
70
- }
71
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Tracking.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- /**
3
- * Handles tracking data
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
9
- * @version $Id: Tracking.php 20.08.13 11:35 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_Tracking
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- /**
16
- * @var array
17
- */
18
- protected $_trackingAdapter;
19
-
20
- /**
21
- * {@inheritdoc}
22
- */
23
- protected function configureFacade() {}
24
-
25
- /**
26
- * Get tracking adapter
27
- *
28
- * @return tracking adapter object
29
- */
30
- public function getTrackingAdapter()
31
- {
32
- if($this->_trackingAdapter === null)
33
- {
34
- if(Mage::helper('factfinder')->useOldTracking()) {
35
- $this->_trackingAdapter = Mage::getModel('factfinder/handler_tracking_scic');
36
- }
37
- // If old tracking was not activated use the new tracking
38
- if ($this->_trackingAdapter === null) {
39
- $this->_trackingAdapter = $this->_getFacade()->getTrackingAdapter();
40
- }
41
- if ($this->_trackingAdapter === null)
42
- $this->_trackingAdapter = array();
43
- }
44
- return $this->_trackingAdapter;
45
- }
46
-
47
- /**
48
- * Fire tracking request
49
- *
50
- * @return mixed|null
51
- */
52
- public function applyTracking()
53
- {
54
- if (Mage::helper('factfinder')->useLegacyTracking()) {
55
- $result = $this->_getFacade()->applyLegacyTracking();
56
- } else if(Mage::helper('factfinder')->useOldTracking()) {
57
- $result = $this->_getFacade()->applyScicTracking();
58
- } else {
59
- $result = $this->_getFacade()->applyTracking();
60
- }
61
-
62
- return $result;
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Handler/Tracking/Scic.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
- /**
3
- * Creates a mapping between new and old tracking methods
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
9
- * @version $Id: Scic.php 26.08.13 15:05 $
10
- *
11
- **/
12
- class Flagbit_FactFinder_Model_Handler_Tracking_Scic
13
- extends Flagbit_FactFinder_Model_Handler_Abstract
14
- {
15
- protected function configureFacade() {}
16
-
17
- /**
18
- * Mapping method from new -> old tracking
19
- *
20
- * @param $event
21
- * @param $inputParams
22
- * @return FACTFinder_Default_ScicAdapter
23
- */
24
- public function setupEventTracking($event, $inputParams)
25
- {
26
- /* @var $scicAdapter FACTFinder_Default_ScicAdapter */
27
- if (Mage::helper('factfinder')->useLegacyTracking()) {
28
- $scicAdapter = $this->_getFacade()->getLegacyTrackingAdapter();
29
- } else {
30
- $scicAdapter = $this->_getFacade()->getScicAdapter();
31
- }
32
-
33
- switch ($event) {
34
- case FACTFinder_Default_TrackingAdapter::EVENT_INSPECT:
35
- $searchHelper = $searchHelper = Mage::helper('factfinder/search');
36
- $scicAdapter->setupClickTracking(
37
- $inputParams['id'],
38
- $inputParams['sid'],
39
- $searchHelper->getQuery()->getQueryText(),
40
- 1, //pos
41
- 1, //origPos
42
- 1, //page
43
- $inputParams['product']->getSimilarity(),
44
- $inputParams['product']->getName(),
45
- $searchHelper->getPageLimit(),
46
- $searchHelper->getDefaultPerPageValue());
47
- break;
48
- case FACTFinder_Default_TrackingAdapter::EVENT_CART:
49
- $scicAdapter->setupCartTracking(
50
- $inputParams['id'],
51
- $inputParams['sid'],
52
- $inputParams['amount'],
53
- $inputParams['price'],
54
- $inputParams['uid']
55
- );
56
- break;
57
- case FACTFinder_Default_TrackingAdapter::EVENT_BUY:
58
- $scicAdapter->setupCheckoutTracking(
59
- $inputParams['id'],
60
- $inputParams['sid'],
61
- $inputParams['amount'],
62
- $inputParams['price'],
63
- $inputParams['uid']
64
- );
65
- break;
66
- case FACTFinder_Default_TrackingAdapter::EVENT_DISPLAY:
67
- case FACTFinder_Default_TrackingAdapter::EVENT_FEEDBACK:
68
- case FACTFinder_Default_TrackingAdapter::EVENT_AVAILABILITY_CHECK:
69
- case FACTFinder_Default_TrackingAdapter::EVENT_CACHE_HIT:
70
- case FACTFinder_Default_TrackingAdapter::EVENT_SESSION_START:
71
- // Not implemented yet
72
- break;
73
- }
74
-
75
- return $scicAdapter;
76
- }
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Block class for upselling
12
- *
13
- * Rewritten block - data is now caught by FACT-Finder, passed to normal collection, works quite as if it was the
14
- * default behavior.
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Jörg Weller <weller@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_Model_Layer extends Flagbit_FactFinder_Model_Layer_Abstract
23
- {
24
- const XML_PATH_DISPLAY_LAYER_COUNT = 'catalog/search/use_layered_navigation_count';
25
-
26
- protected $_productCollection = null;
27
-
28
- /**
29
- * Get current layer product collection
30
- *
31
- * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
32
- */
33
- public function getProductCollection()
34
- {
35
- if(!Mage::helper('factfinder/search')->getIsEnabled()){
36
- return parent::getProductCollection();
37
- }
38
-
39
- // handle search
40
- if($this instanceof Mage_CatalogSearch_Model_Layer){
41
- if(is_null($this->_productCollection)){
42
- $this->_productCollection = Mage::getResourceModel('factfinder/search_collection');
43
- $this->prepareProductCollection($this->_productCollection);
44
- }
45
- $collection = $this->_productCollection;
46
-
47
- // handle category listing
48
- }else{
49
- if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
50
- $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
51
- }
52
- else {
53
- //$collection = $this->getCurrentCategory();
54
- $collection = Mage::getResourceModel('factfinder/search_collection');
55
- $this->prepareProductCollection($collection);
56
- $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
57
- }
58
- }
59
-
60
-
61
- return $collection;
62
- }
63
-
64
- /**
65
- * Get collection of all filterable attributes for layer products set
66
- *
67
- * @return Flagbit_FactFinder_Model_Mysql4_Product_Attribute_Collection
68
- */
69
- public function getFilterableAttributes()
70
- {
71
-
72
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
73
- return parent::getFilterableAttributes();
74
- }
75
-
76
- /* @var $collection Flagbit_FactFinder_Model_Mysql4_Product_Attribute_Collection */
77
- $collection = Mage::getResourceModel('factfinder/product_attribute_collection')
78
- ->setItemObjectClass('catalog/resource_eav_attribute')
79
- ->setStoreId(Mage::app()->getStore()->getId());
80
-
81
- return $collection;
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer/Abstract.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
-
3
- if(Mage::helper('factfinder/search')->getIsOnSearchPage()){
4
- class Flagbit_FactFinder_Model_Layer_Abstract extends Mage_CatalogSearch_Model_Layer {}
5
- }else{
6
- class Flagbit_FactFinder_Model_Layer_Abstract extends Mage_Catalog_Model_Layer {}
7
- }
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Abstract.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Price export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Layer_Filter_Attribute_Abstract extends Mage_Catalog_Model_Layer_Filter_Attribute {
22
-
23
- /**
24
- * Array of Magento Layer Filter Items
25
- * @var mixed
26
- */
27
- protected $_filterItems = null;
28
-
29
- /**
30
- * Array of Selected Layer Filters
31
- * @var mixed
32
- */
33
- protected $_selectedFilterItems = array();
34
-
35
- /**
36
- * Apply attribute option filter to product collection
37
- *
38
- * @param Zend_Controller_Request_Abstract $request
39
- * @param Varien_Object $filterBlock
40
- * @return Mage_Catalog_Model_Layer_Filter_Attribute
41
- */
42
- public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
43
- {
44
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
45
- return parent::apply($request, $filterBlock);
46
- }
47
- $this->_getItemsData();
48
- $_attributeCode = $filterBlock->getAttributeModel()->getAttributeCode();
49
- if (isset($this->_selectedFilterItems[$_attributeCode])
50
- && is_array($this->_selectedFilterItems[$_attributeCode])) {
51
-
52
- foreach($this->_selectedFilterItems[$_attributeCode] as $option){
53
- $this->getLayer()->getState()->addFilter($this->_createItem($option['label'], $option['value']));
54
- }
55
- }
56
- return $this;
57
- }
58
-
59
- /**
60
- * Create filter item object
61
- *
62
- * @param string $label
63
- * @param mixed $value
64
- * @param int $count
65
- * @return Mage_Catalog_Model_Layer_Filter_Item
66
- */
67
- protected function _createItem($label, $value, $count=0)
68
- {
69
-
70
- if (!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')) {
71
- return parent::_createItem($label, $value, $count);
72
- }
73
-
74
- return Mage::getModel('factfinder/layer_filter_item')
75
- ->setFilter($this)
76
- ->setLabel($label)
77
- ->setValue($value)
78
- ->setCount($count);
79
- }
80
-
81
-
82
- /**
83
- * Get data array for building attribute filter items
84
- *
85
- * @return array
86
- */
87
- protected function _getItemsData()
88
- {
89
- if(!Mage::helper('factfinder/search')->getIsEnabled(false, 'asn')){
90
- return parent::_getItemsData();
91
- }
92
-
93
- if($this->_filterItems === null){
94
- $attribute = $this->getAttributeModel();
95
- $this->_requestVar = $attribute->getAttributeCode();
96
-
97
- $key = $this->getLayer()->getStateKey().'_'.$this->_requestVar;
98
- $data = $this->getLayer()->getAggregator()->getCacheData($key);
99
-
100
- $options = $attribute->getItems();
101
- $optionsCount = $attribute->getCount();
102
- $this->_filterItems = array();
103
- if(is_array($options)){
104
- foreach ($options as $option) {
105
-
106
- if($option['selected'] == true){
107
- $this->_selectedFilterItems[$attribute->getAttributeCode()][] = $option;
108
- continue;
109
- }
110
- $this->_filterItems[] = $option;
111
- }
112
- }
113
- }
114
-
115
- return $this->_filterItems;
116
- }
117
-
118
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Catalog.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Price export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Layer_Filter_Attribute_Catalog extends Flagbit_FactFinder_Model_Layer_Filter_Attribute_Abstract {
22
-
23
-
24
-
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Attribute/Catalogsearch.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * This helper class provides the Price export
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Layer_Filter_Attribute_Catalogsearch extends Flagbit_FactFinder_Model_Layer_Filter_Attribute_Abstract {
22
-
23
-
24
- /**
25
- * Check whether specified attribute can be used in LN
26
- *
27
- * @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
28
- * @return bool
29
- */
30
- protected function _getIsFilterableAttribute($attribute)
31
- {
32
- return $attribute->getIsFilterableInSearch();
33
- }
34
-
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Layer/Filter/Item.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- class Flagbit_FactFinder_Model_Layer_Filter_Item extends Mage_Catalog_Model_Layer_Filter_Item {
3
-
4
-
5
- /**
6
- * Get url for remove item from filter
7
- *
8
- * @return string
9
- */
10
- public function getRemoveUrl()
11
- {
12
- if (strtolower($this->getFilter()->getRequestVar()) == 'category' || $this->getValue() != '') {
13
- $query = array($this->getFilter()->getRequestVar()=>$this->getValue());
14
- $params['_current'] = true;
15
- $params['_use_rewrite'] = true;
16
- $params['_query'] = $query;
17
- $params['_escape'] = true;
18
- return Mage::getUrl('*/*/*', $params);
19
- } else {
20
- return parent::getRemoveUrl();
21
- }
22
- }
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Campaign/Pushedproducts/Collection.php DELETED
@@ -1,148 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Search Collection with FACT-Finder Search Results
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id: Collection.php 644 2011-03-17 13:26:59Z weller $
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Campaign_Pushedproducts_Collection
22
- extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
23
- {
24
- /**
25
- * Get collection size
26
- *
27
- * @return int
28
- */
29
- public function getSize()
30
- {
31
- return count($this->_getCampaign()->getPushedProducts());
32
- }
33
-
34
- /**
35
- * get Campaign
36
- *
37
- * @return FACTFinder_Campaign
38
- */
39
- protected function _getCampaign()
40
- {
41
- if(Mage::helper('factfinder/search')->getIsEnabled(false, 'campaign')){
42
- return Mage::getSingleton('factfinder/handler_search')->getCampaigns();
43
- }
44
-
45
- return null;
46
- }
47
-
48
- /**
49
- * Load entities records into items
50
- *
51
- * @return Mage_Eav_Model_Entity_Collection_Abstract
52
- */
53
- public function _loadEntities($printQuery = false, $logQuery = false)
54
- {
55
-
56
- $productIds = array();
57
- $campaigns = $this->_getCampaign();
58
-
59
- if (!$campaigns) {
60
- return $this;
61
- }
62
-
63
- foreach($campaigns->getPushedProducts() as $record){
64
- $productIds[$record->getId()] = new Varien_Object(
65
- array(
66
- 'similarity' => $record->getSimilarity(),
67
- 'position' => $record->getPosition(),
68
- 'original_position' => $record->getOriginalPosition()
69
- )
70
- );
71
- }
72
- $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
73
-
74
- if (!empty($productIds)) {
75
-
76
- // add Filter to Query
77
- $this->addFieldToFilter(
78
- $idFieldName,
79
- array('in'=>array_keys($productIds))
80
- );
81
-
82
- $this->_pageSize = null;
83
- $entity = $this->getEntity();
84
-
85
- $this->getSelect()->reset(Zend_Db_Select::LIMIT_COUNT);
86
- $this->getSelect()->reset(Zend_Db_Select::LIMIT_OFFSET);
87
-
88
- $this->printLogQuery($printQuery, $logQuery);
89
- Mage::helper('factfinder/debug')->log('Search SQL Query: '.$this->getSelect()->__toString());
90
-
91
- try {
92
- $rows = $this->_fetchAll($this->getSelect());
93
- } catch (Exception $e) {
94
- Mage::printException($e, $this->getSelect());
95
- $this->printLogQuery(true, true, $this->getSelect());
96
- throw $e;
97
- }
98
-
99
- $items = array();
100
- foreach ($rows as $v) {
101
- $items[$v[$idFieldName]] = $v;
102
- }
103
-
104
- foreach ($productIds as $productId => $additionalData){
105
-
106
- if(empty($items[$productId])){
107
- continue;
108
- }
109
- $v = array_merge($items[$productId], $additionalData->toArray());
110
- $object = $this->getNewEmptyItem()
111
- ->setData($v);
112
-
113
- $this->addItem($object);
114
- if (isset($this->_itemsById[$object->getId()])) {
115
- $this->_itemsById[$object->getId()][] = $object;
116
- }
117
- else {
118
- $this->_itemsById[$object->getId()] = array($object);
119
- }
120
- }
121
-
122
- }
123
- return $this;
124
- }
125
-
126
- /**
127
- * Add search query filter
128
- *
129
- * @param Mage_CatalogSearch_Model_Query $query
130
- * @return Mage_CatalogSearch_Model_Mysql4_Search_Collection
131
- */
132
- public function addSearchFilter($query)
133
- {
134
- return $this;
135
- }
136
-
137
- /**
138
- * Set Order field
139
- *
140
- * @param string $attribute
141
- * @param string $dir
142
- * @return Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection
143
- */
144
- public function setOrder($attribute, $dir='desc')
145
- {
146
- return $this;
147
- }
148
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Product/Attribute/Collection.php DELETED
@@ -1,144 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Filter Attribute Collection
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Product_Attribute_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Collection {
22
-
23
- protected $_result = null;
24
- protected $_attributeLabels = null;
25
- protected $_storeId = null;
26
-
27
- /**
28
- * Get collection size
29
- *
30
- * @return int
31
- */
32
- public function getSize()
33
- {
34
- return count($this->_getSearchHandler()->getAfterSearchNavigation());
35
- }
36
-
37
- /**
38
- * get Facade
39
- *
40
- * @return Flagbit_FactFinder_Model_Facade
41
- */
42
- protected function _getSearchHandler()
43
- {
44
- return Mage::getSingleton('factfinder/handler_search');
45
- }
46
-
47
- /**
48
- * Load entities records into items
49
- *
50
- * @return Mage_Eav_Model_Entity_Collection_Abstract
51
- */
52
- public function load($printQuery = false, $logQuery = false)
53
- {
54
- if ($this->isLoaded()) {
55
- return $this;
56
- }
57
-
58
- $result = $this->_getSearchHandler()->getAfterSearchNavigation();
59
-
60
- if (count($result)) {
61
- $this->resetData();
62
-
63
- foreach ($result as $row) {
64
- $item = $this->getNewEmptyItem();
65
- if ($this->getIdFieldName()) {
66
- $item->setIdFieldName($this->getIdFieldName());
67
- }
68
- $row['store_label'] = $this->_getStoreLabelsByAttributeCode($row['name']);
69
- $item->addData($row);
70
- $this->addItem($item);
71
- }
72
-
73
- $this->_setIsLoaded();
74
- $this->_afterLoad();
75
- }
76
- return $this;
77
- }
78
-
79
-
80
- /**
81
- * Add search query filter
82
- *
83
- * @param Mage_CatalogSearch_Model_Query $query
84
- * @return Mage_CatalogSearch_Model_Mysql4_Search_Collection
85
- */
86
- public function addSearchFilter($query)
87
- {
88
- return $this;
89
- }
90
-
91
- /**
92
- * Retrieve store labels by given attribute code
93
- *
94
- * @param string $attributeCode
95
- * @return array
96
- */
97
- protected function _getStoreLabelsByAttributeCode($attributeCode)
98
- {
99
- if($this->_attributeLabels === null){
100
- $entityType = Mage::getSingleton('eav/config')->getEntityType('catalog_product');
101
-
102
- $values = array();
103
-
104
- $select = $this->getConnection()->select()
105
- ->from(array('main_table' => $this->getTable('eav/attribute')), array('attribute_code'))
106
- ->joinLeft(
107
- array('additional_table' => $this->getTable('eav/attribute_label')),
108
- 'additional_table.attribute_id = main_table.attribute_id',
109
- null
110
- )
111
- ->columns(array('value' => new Zend_Db_Expr('IF(additional_table.value IS NULL, main_table.frontend_label, additional_table.value)')))
112
- ->where('main_table.entity_type_id = ?', $entityType->getEntityTypeId())
113
- ->where('additional_table.store_id IS NULL OR additional_table.store_id=?', $this->_storeId);
114
-
115
- $this->_attributeLabels = $this->getConnection()->fetchPairs($select);
116
- }
117
- return isset($this->_attributeLabels[$attributeCode]) ? $this->_attributeLabels[$attributeCode] : $attributeCode;
118
- }
119
-
120
- /**
121
- * set Store ID
122
- *
123
- * @param int $storeId
124
- * @return Flagbit_FactFinder_Model_Mysql4_Product_Attribute_Collection
125
- */
126
- public function setStoreId($storeId)
127
- {
128
- $this->_storeId = $storeId;
129
- return $this;
130
- }
131
-
132
- /**
133
- * Set Order field
134
- *
135
- * @param string $attribute
136
- * @param string $dir
137
- * @return Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection
138
- */
139
- public function setOrder($attribute, $dir='desc')
140
- {
141
- return $this;
142
- }
143
-
144
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Product/Recommendation/Collection.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Recommendation based product collection.
12
- *
13
- * Data is caught by FACT-Finder, passed to normal collection, works quite as if it was the default behavior.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <türk@flagbit.de>
19
- * @version $Id: Search.php 678 2011-08-01 13:02:50Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Product_Recommendation_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
22
- {
23
- /**
24
- * Pass the product ids from FACT-Finder to the collection.
25
- *
26
- * @param array $recommendations Array with id information in Objects.
27
- */
28
- public function setRecommendations($recommendations)
29
- {
30
- $ids = array();
31
- foreach ($recommendations as $recommendationItem) {
32
- $ids[] = $recommendationItem->getId();
33
- }
34
-
35
- $searchHelper = Mage::helper('factfinder/search');
36
- $idFieldName = $searchHelper->getIdFieldName();
37
-
38
- $this->addAttributeToFilter($idFieldName, array('in' => $ids));
39
-
40
- $order = new Zend_Db_Expr($this->getConnection()->quoteInto('find_in_set(`e`.`' . $idFieldName . '`, ?)', implode(',', $ids)));
41
- $this->getSelect()->order($order);
42
-
43
- return $this;
44
- }
45
-
46
-
47
- /**
48
- * Helper function to exclude certain products that are already in the cart.
49
- *
50
- * @param array $ninIds Simple array of product ids
51
- */
52
- public function addExcludeProductFilter($ninIds)
53
- {
54
- $this->addAttributeToFilter($this->getIdFieldName(), array('nin' => $ninIds));
55
-
56
- return $this;
57
- }
58
-
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Scic/Queue.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Ressource Model class
12
- *
13
- * Queue for SCIC orders. Orders are sent to FACT-Finder asynchronously by cronjobs.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Scic_Queue extends Mage_Core_Model_Mysql4_Abstract
22
- {
23
-
24
- /**
25
- * Constructor with simple Magento initialisation
26
- */
27
- protected function _construct() {
28
- $this->_init('factfinder/scic_queue', 'id');
29
- }
30
-
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Scic/Queue/Collection.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Collection class
12
- *
13
- * Queue for SCIC orders. Orders are sent to FACT-Finder asynchronously by cronjobs.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Scic_Queue_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
22
- {
23
- protected function _construct()
24
- {
25
- $this->_init('factfinder/scic_queue')
26
- ->setOrder('store_id', 'ASC');
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Search/Collection.php DELETED
@@ -1,135 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Search Collection with FACT-Finder Search Results
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <joerg.weller@flagbit.de>
19
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_Model_Mysql4_Search_Collection
23
- extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
24
- {
25
- /**
26
- * Get collection size
27
- *
28
- * @return int
29
- */
30
- public function getSize()
31
- {
32
- return $this->_getSearchHandler()->getSearchResultCount();
33
- }
34
-
35
- /**
36
- * get Factfinder Facade
37
- *
38
- * @return Flagbit_FactFinder_Model_Handler_Search
39
- */
40
- protected function _getSearchHandler()
41
- {
42
- return Mage::getSingleton('factfinder/handler_search');
43
- }
44
-
45
- /**
46
- * Load entities records into items
47
- *
48
- * @return Mage_Eav_Model_Entity_Collection_Abstract
49
- */
50
- public function _loadEntities($printQuery = false, $logQuery = false)
51
- {
52
- // get product IDs from Fact-Finder
53
- $productIds = $this->_getSearchHandler()->getSearchResult();
54
-
55
- $searchResult = Mage::getSingleton('factfinder/facade')->getSearchResult();
56
- if($searchResult && $refKey = $searchResult->getRefKey()) {
57
- Mage::getSingleton('core/session')->setFactFinderRefKey($refKey);
58
- }
59
-
60
- if (!empty($productIds)) {
61
- $idFieldName = Mage::helper('factfinder/search')->getIdFieldName();
62
-
63
- // add Filter to Query
64
- $this->addFieldToFilter(
65
- $idFieldName,
66
- array('in'=>array_keys($productIds))
67
- );
68
-
69
- $this->_pageSize = null;
70
- $entity = $this->getEntity();
71
-
72
- $this->getSelect()->reset(Zend_Db_Select::LIMIT_COUNT);
73
- $this->getSelect()->reset(Zend_Db_Select::LIMIT_OFFSET);
74
-
75
- $this->printLogQuery($printQuery, $logQuery);
76
- Mage::helper('factfinder/debug')->log('Search SQL Query: '.$this->getSelect()->__toString());
77
-
78
- try {
79
- $rows = $this->_fetchAll($this->getSelect());
80
- } catch (Exception $e) {
81
- Mage::printException($e, $this->getSelect());
82
- $this->printLogQuery(true, true, $this->getSelect());
83
- throw $e;
84
- }
85
-
86
- $items = array();
87
- foreach ($rows as $v) {
88
- $items[trim($v[$idFieldName])] = $v;
89
- }
90
-
91
- foreach ($productIds as $productId => $additionalData){
92
-
93
- if(empty($items[$productId])){
94
- continue;
95
- }
96
- $v = array_merge($items[$productId], $additionalData->toArray());
97
- $object = $this->getNewEmptyItem()
98
- ->setData($v);
99
-
100
- $this->addItem($object);
101
- if (isset($this->_itemsById[$object->getId()])) {
102
- $this->_itemsById[$object->getId()][] = $object;
103
- }
104
- else {
105
- $this->_itemsById[$object->getId()] = array($object);
106
- }
107
- }
108
-
109
- }
110
- return $this;
111
- }
112
-
113
- /**
114
- * Add search query filter
115
- *
116
- * @param Mage_CatalogSearch_Model_Query $query
117
- * @return Mage_CatalogSearch_Model_Mysql4_Search_Collection
118
- */
119
- public function addSearchFilter($query)
120
- {
121
- return $this;
122
- }
123
-
124
- /**
125
- * Set Order field
126
- *
127
- * @param string $attribute
128
- * @param string $dir
129
- * @return Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection
130
- */
131
- public function setOrder($attribute, $dir='desc')
132
- {
133
- return $this;
134
- }
135
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Mysql4/Search/Engine.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * FACT-Finder Search Engine Model
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_Mysql4_Search_Engine extends Mage_CatalogSearch_Model_Mysql4_Fulltext_Engine
22
- {
23
-
24
- /**
25
- * Retrieve fulltext search result data collection
26
- *
27
- * @return Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection
28
- */
29
- public function getResultCollection()
30
- {
31
- return Mage::getResourceModel('factfinder/search_collection');
32
- }
33
-
34
- /**
35
- * Define if Layered Navigation is allowed
36
- *
37
- * @return bool
38
- */
39
- public function isLeyeredNavigationAllowed()
40
- {
41
- return true;
42
- }
43
-
44
- /**
45
- * Define if engine is avaliable
46
- *
47
- * @return bool
48
- */
49
- public function test()
50
- {
51
- return Mage::helper('factfinder/search')->getIsEnabled(false, 'asn');
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Observer.php DELETED
@@ -1,394 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Observer for Magento events.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <michael.tuerk@flagbit.de>
19
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
20
- * @version $Id: Observer.php 26.08.13 15:05 $
21
- */
22
- class Flagbit_FactFinder_Model_Observer
23
- {
24
- const _asnBlockRegistryKey = 'FACTFINDER__asnBlock';
25
- const _campaignRedirectRegistryKey = 'FACTFINDER__campaignRedirectBlock';
26
-
27
- /**
28
- * Observer method.
29
- * Sends information to FACT-Finder if item was added to cart.
30
- *
31
- * @param Varien_Event_Observer $observer
32
- */
33
- public function addToCartSendSCIC($observer)
34
- {
35
- if (!Mage::getStoreConfigFlag('factfinder/export/track_carts')) {
36
- return;
37
- }
38
-
39
- $quoteItem = $observer->getQuoteItem();
40
- $product = $observer->getProduct();
41
-
42
- $searchHelper = Mage::helper('factfinder/search');
43
- $idFieldName = $searchHelper->getIdFieldName();
44
-
45
- $qty = $quoteItem->getQty();
46
-
47
- $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
48
- if ($customerId) {
49
- $customerId = md5('customer_' . $customerId);
50
- }
51
-
52
- try {
53
- /* @var $tracking Flagbit_FactFinder_Model_Handler_Tracking */
54
- $tracking = Mage::getModel('factfinder/handler_tracking');
55
- $tracking->getTrackingAdapter()->setupEventTracking(
56
- FACTFinder_Default_TrackingAdapter::EVENT_CART,
57
- array(
58
- 'id' => $product->getData($idFieldName),
59
- 'sid' => md5(Mage::getSingleton('core/session')->getSessionId()),
60
- 'amount' => $qty,
61
- 'price' => $product->getFinalPrice($qty),
62
- 'uid' => $customerId,
63
- 'site' => Mage::app()->getStore()->getCode(),
64
- 'sourceRefKey' => Mage::getSingleton('core/session')->getFactFinderRefKey()
65
- )
66
- );
67
- $tracking->applyTracking();
68
- }
69
- catch (Exception $e) {
70
- Mage::helper('factfinder/debug')->log($e->getMessage());
71
- }
72
- }
73
-
74
- /**
75
- * Tracking of single product click
76
- *
77
- * @param $product
78
- */
79
- protected function sendClickTrackingForSingleProduct($product)
80
- {
81
- $searchHelper = Mage::helper('factfinder/search');
82
-
83
- if (!$searchHelper->getIsEnabled(false, 'clicktracking')) {
84
- return;
85
- }
86
-
87
- try {
88
- $idFieldName = $searchHelper->getIdFieldName();
89
-
90
- $customerId = Mage::getSingleton('customer/session')->getCustomer()->getId();
91
- if ($customerId) {
92
- $customerId = md5('customer_' . $customerId);
93
- }
94
-
95
- /* @var $tracking Flagbit_FactFinder_Model_Handler_Tracking */
96
- $tracking = Mage::getModel('factfinder/handler_tracking');
97
- $tracking->getTrackingAdapter()->setupEventTracking(
98
- FACTFinder_Default_TrackingAdapter::EVENT_INSPECT,
99
- array(
100
- 'id' => $product->getData($idFieldName),
101
- 'sid' => md5(Mage::getSingleton('core/session')->getSessionId()),
102
- 'price' => $product->getFinalPrice(),
103
- 'uid' => $customerId,
104
- 'site' => Mage::app()->getStore()->getCode(),
105
- 'sourceRefKey' => Mage::getSingleton('core/session')->getFactFinderRefKey(),
106
- 'product' => $product
107
- )
108
- );
109
- $tracking->applyTracking();
110
- }
111
- catch (Exception $e) {
112
- Mage::helper('factfinder/debug')->log($e->getMessage());
113
- }
114
- }
115
-
116
- /**
117
- * Observer method
118
- * Adds all ordered items to queue that is sent to FACT-Finder by Cronjob.
119
- *
120
- * @param Varien_Event_Observer $observer
121
- */
122
- public function addOrderDetailsToSCICQueue($observer)
123
- {
124
- if (!Mage::getStoreConfigFlag('factfinder/export/track_checkout')) {
125
- return;
126
- }
127
-
128
- $order = $observer->getOrder();
129
- $customerId = $order->getCustomerId();
130
- if ($customerId) {
131
- $customerId = md5('customer_' . $customerId);
132
- }
133
-
134
- $searchHelper = Mage::helper('factfinder/search');
135
- $idFieldName = $searchHelper->getIdFieldName();
136
- if ($idFieldName == 'entity_id') {
137
- $idFieldName = 'product_id'; // sales_order_item does not contain a entity_id
138
- }
139
-
140
- foreach ($order->getAllItems() as $item) {
141
- if ($item->getParentItem() != null) {
142
- continue;
143
- }
144
-
145
- try {
146
- Mage::getModel('factfinder/scic_queue')
147
- ->setProductId($item->getData($idFieldName))
148
- ->setSid(md5(Mage::getSingleton('core/session')->getSessionId()))
149
- ->setUserid($customerId)
150
- ->setPrice($item->getPrice())
151
- ->setCount($item->getQtyOrdered())
152
- ->setStoreId(Mage::app()->getStore()->getId())
153
- ->save();
154
- }
155
- catch (Exception $e) {
156
- Mage::logException($e);
157
- }
158
- }
159
- }
160
-
161
-
162
- /**
163
- * Cronjob observer method.
164
- * Processes all orders given in SCIC queue and sends them to FACT-Finder.
165
- *
166
- */
167
- public function processScicOrderQueue()
168
- {
169
- $queue = Mage::getModel('factfinder/scic_queue');
170
- $collection = $queue->getCollection()->addOrder('store_id', 'ASC');
171
-
172
- $storeId = null;
173
- $scic = null;
174
- foreach ($collection as $item) {
175
- try {
176
- $facade = Mage::getModel('factfinder/facade');
177
- if ($item->getStoreId() != $storeId) {
178
- $facade->setStoreId($item->getStoreId());
179
- $storeId = $item->getStoreId();
180
- }
181
-
182
- /* @var $tracking Flagbit_FactFinder_Model_Handler_Tracking */
183
- $tracking = Mage::getModel('factfinder/handler_tracking');
184
- $tracking->getTrackingAdapter()->setupEventTracking(
185
- FACTFinder_Default_TrackingAdapter::EVENT_BUY,
186
- array(
187
- 'id' => $item->getProductId(),
188
- 'sid' => $item->getSid(),
189
- 'amount' => $item->getCount(),
190
- 'price' => $item->getPrice(),
191
- 'uid' => md5('customer_' . $item->getUserid()),
192
- 'site' => Mage::app()->getStore($storeId)->getCode(),
193
- 'sourceRefKey' => ''
194
- )
195
- );
196
- $tracking->applyTracking();
197
-
198
- $item->delete($item);
199
- }
200
- catch (Exception $e) {
201
- Mage::logException($e);
202
- }
203
- }
204
- }
205
-
206
-
207
- /**
208
- * Checks configuration data before saving it to database.
209
- *
210
- * @param Varien_Event_Observer $observer
211
- */
212
- public function setEnabledFlagInFactFinderConfig($observer)
213
- {
214
- $request = $observer->getControllerAction()->getRequest();
215
- if ($request->getParam('section') != 'factfinder') {
216
- return;
217
- }
218
-
219
- $groups = $request->getPost('groups');
220
- $website = $request->getParam('website');
221
- $store = $request->getParam('store');
222
-
223
- if (
224
- is_array($groups['search'])
225
- && is_array($groups['search']['fields'])
226
- && is_array($groups['search']['fields']['enabled'])
227
- && isset($groups['search']['fields']['enabled']['value'])
228
- ) {
229
- $value = $groups['search']['fields']['enabled']['value'];
230
- }
231
- elseif ($store) {
232
- $value = Mage::app()->getWebsite($website)->getConfig('factfinder/search/enabled');
233
- }
234
- else {
235
- $value = (string) Mage::getConfig()->getNode('default/factfinder/search/enabled');
236
- }
237
-
238
- if (!$value) {
239
- return;
240
- }
241
-
242
- $errors = Mage::helper('factfinder/backend')->checkConfigData($groups['search']['fields']);
243
- if (!empty($errors)) {
244
- $groups['search']['fields']['enabled']['errors'] = $errors;
245
- } else {
246
- // If there were no errors, reset the fallback feature
247
- Mage::helper('factfinder/search')->resetFailedAttemptCount();
248
- }
249
-
250
- // if we have an error - unset inherit field so that Backend model processing is activated
251
- if (!empty($errors) && isset($groups['search']['fields']['enabled']['inherit'])) {
252
- unset($groups['search']['fields']['enabled']['inherit']);
253
- $groups['search']['fields']['enabled']['value'] = $value;
254
- }
255
-
256
- $request->setPost('groups', $groups);
257
- }
258
-
259
-
260
- /**
261
- * Replaces the link to the management cockpit functionality in the Magento Backend with the external link that
262
- * opens in a new browser tab. Pretty dirty solution, but Magento does not offer any possibility to edit link urls
263
- * in its backend menu model, nor does it allow to add absolute links for external sites.
264
- *
265
- * @param Varien_Event_Observer $observer
266
- */
267
- public function rewriteBackendMenuHtmlForCockpitRedirect($observer)
268
- {
269
- $block = $observer->getBlock();
270
- if ($block->getNameInLayout() != 'menu') {
271
- return;
272
- }
273
-
274
- $transport = $observer->getTransport();
275
- $html = $transport->getHtml();
276
-
277
- $matches = array();
278
- $label = preg_quote(Mage::helper('factfinder')->__('FACT-Finder Business User Cockpit'));
279
- $pattern = '/(\<a[^\>]*href=\"([^\"]*)\"[^\>]*)\>\w*\<span\>\w*' . $label . '\w*\<\/span\>/msU';
280
- if (preg_match($pattern, $html, $matches)) {
281
- $url = Mage::getSingleton('factfinder/facade')->getManagementUrl();
282
- $replace = str_replace($matches[2], $url, $matches[1]) . ' target="_blank"';
283
-
284
- $transport->setHtml(str_replace($matches[1], $replace, $html));
285
- }
286
- }
287
-
288
- /**
289
- * Adds layout handles based on FACT-Finder configuration.
290
- *
291
- * @param Varien_Event_Observer $observer
292
- */
293
- public function addActivationLayoutHandles($observer)
294
- {
295
- if (Mage::helper('factfinder/search')->getIsEnabled(false, 'suggest')) {
296
- $layout = $observer->getLayout();
297
- $update = $layout->getUpdate();
298
- $update->addHandle('factfinder_suggest_enabled');
299
-
300
- if (Mage::getStoreConfig('factfinder/search/ffversion') <= 67)
301
- {
302
- $layout = $observer->getLayout();
303
- $update = $layout->getUpdate();
304
- $update->addHandle('factfinder_suggest_version_lt67');
305
- }
306
- else
307
- {
308
- $layout = $observer->getLayout();
309
- $update = $layout->getUpdate();
310
- $update->addHandle('factfinder_suggest_version_gt68');
311
- }
312
- }
313
-
314
- $request = Mage::app()->getRequest();
315
- //catalogsearch_result_index
316
- if (Mage::helper('factfinder/search')->getIsEnabled(false, 'clicktracking')
317
- && $request->getModuleName() == 'catalogsearch'
318
- && $request->getControllerName() == 'result'
319
- && $request->getActionName() == 'index') {
320
- $layout = $observer->getLayout();
321
- $update = $layout->getUpdate();
322
- $update->addHandle('factfinder_clicktracking_enabled');
323
- }
324
- }
325
-
326
- public function initializeAfterSearchNavigation()
327
- {
328
- $asnBlock = Mage::registry(self::_asnBlockRegistryKey);
329
- if($asnBlock instanceof Flagbit_FactFinder_Block_Layer)
330
- {
331
- $asnBlock->initializeAfterSearchNavigation();
332
- }
333
- }
334
-
335
- /**
336
- * Handle redirects in this single method to control the execution order.
337
- *
338
- * @param Varien_Event_Observer $observer
339
- */
340
- public function handleRedirects(Varien_Event_Observer $observer)
341
- {
342
- $this->_handleCampaignRedirect();
343
- $this->_redirectToProductIfSingleResult();
344
- }
345
-
346
- /**
347
- * Checks if the result set's size is one. If so the user is redirected to the product detail page. This is checked
348
- * right before the first block is rendered so headers can still be sent. The ordinary collection load event is
349
- * triggered too late.
350
- *
351
- */
352
- protected function _redirectToProductIfSingleResult()
353
- {
354
- if (!Mage::helper('factfinder/search')->getIsEnabled() || !Mage::helper('factfinder/search')->getIsOnSearchPage() || Mage::registry('redirectAlreadyChecked')) {
355
- return;
356
- }
357
-
358
- Mage::register('redirectAlreadyChecked', 1);
359
- if (Mage::getStoreConfig('factfinder/config/redirectOnSingleResult')) {
360
- $block = Mage::app()->getLayout()->getBlock('search_result_list');
361
-
362
- if (!$block instanceof Mage_Catalog_Block_Product_List) {
363
- return;
364
- }
365
-
366
- $collection = $block->getLoadedProductCollection();
367
- $collection->load();
368
-
369
- if (count($collection) == 1) {
370
- $product = $collection->getFirstItem();
371
-
372
- $this->sendClickTrackingForSingleProduct($product);
373
-
374
- $response = Mage::app()->getResponse();
375
- $response->setRedirect($product->getProductUrl(false));
376
- $response->sendResponse();
377
- exit;
378
- }
379
- }
380
- }
381
-
382
- /**
383
- * Handle campaign redirects
384
- *
385
- */
386
- protected function _handleCampaignRedirect()
387
- {
388
- $redirectBlock = Mage::registry(self::_campaignRedirectRegistryKey);
389
- if($redirectBlock instanceof Flagbit_FactFinder_Block_Layer)
390
- {
391
- $redirectBlock->handleCampaignRedirect();
392
- }
393
- }
394
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Processor.php DELETED
@@ -1,281 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- require_once BP.DS.'lib'.DS.'FACTFinder'.DS.'Loader.php';
11
-
12
- /**
13
- * Model class
14
- *
15
- * Request Processor for fast handling
16
- *
17
- * @category Mage
18
- * @package Flagbit_FactFinder
19
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
20
- * @author Joerg Weller <weller@flagbit.de>
21
- * @version $Id$
22
- */
23
- class Flagbit_FactFinder_Model_Processor
24
- {
25
-
26
- const CACHE_TAG = 'FACTFINDER'; // Cache Tag
27
- const REQUEST_ID_PREFIX = 'FACTFINDER_';
28
- const XML_CONFIG_PATH = 'factfinder/search/';
29
-
30
-
31
- /**
32
- * FactFinder Facade
33
- * @var Flagbit_FactFinder_Model_Facade
34
- */
35
- protected $_facade;
36
-
37
- /**
38
- * @var array with loaded config values
39
- */
40
- protected $_config;
41
-
42
- /**
43
- * Class constructor
44
- */
45
- public function __construct()
46
- {
47
- $uri = $this->_getFullPageUrl();
48
-
49
- $this->_requestId = $uri;
50
- $this->_requestCacheId = $this->prepareCacheId($this->_requestId);
51
- $this->_requestTags = array(self::CACHE_TAG);
52
- }
53
-
54
- /**
55
- * get Fact-Finder Facade
56
- * we do it manually, because we do not have the full magento context
57
- *
58
- * @return Flagbit_FactFinder_Model_Facade
59
- */
60
- protected function _getFacade()
61
- {
62
- if($this->_facade === null){
63
- $logger = new Flagbit_FactFinder_Helper_Debug();
64
- $this->_facade = new Flagbit_FactFinder_Model_Facade($logger);
65
- }
66
- return $this->_facade;
67
- }
68
-
69
-
70
- /**
71
- * Get page content from cache storage
72
- *
73
- * @param string $content
74
- * @return string | false
75
- */
76
- public function extractContent($content)
77
- {
78
- // handle in App Request if "factfinder" in Request path
79
- if (!$content
80
- && strpos($this->_requestId, 'factfinder')
81
- && $this->isAllowed()) {
82
-
83
- $requestCacheId = $this->prepareCacheId($this->getRequestId().'request');
84
- $request = Mage::app()->loadCache($requestCacheId);
85
- if ($request) {
86
- $content = $this->handleWithoutAppRequest($request);
87
- }
88
-
89
- }
90
- return $content;
91
- }
92
-
93
- /**
94
- * handle in App Requests
95
- *
96
- * @param string $request
97
- * @return string
98
- */
99
- public function handleInAppRequest($request)
100
- {
101
- $requestCacheId = $this->prepareCacheId($this->getRequestId().'request');
102
- Mage::app()->saveCache($request, $requestCacheId, $this->getRequestTags());
103
-
104
- $configCacheId = $this->prepareCacheId($this->getRequestId().'config');
105
- $this->_config = Mage::getStoreConfig('factfinder/search');
106
- Mage::app()->saveCache(serialize($this->_config), $configCacheId, $this->getRequestTags());
107
-
108
- return $this->_handleRequest($request);
109
- }
110
-
111
- /**
112
- * hanlde without App Requests
113
- *
114
- * @param string $request
115
- * @return string
116
- */
117
- public function handleWithoutAppRequest($request)
118
- {
119
- $configCacheId = $this->prepareCacheId($this->getRequestId().'config');
120
- $config = null;
121
- try{
122
- $this->_config = unserialize(Mage::app()->loadCache($configCacheId));
123
- } catch (Exception $e){
124
- return;
125
- }
126
- if(!is_array($this->_config) || empty($this->_config)){
127
- return;
128
- }
129
- $this->_getFacade()->setConfiguration($this->_config);
130
- return $this->_handleRequest($request);
131
- }
132
-
133
- /**
134
- * handle Requests
135
- *
136
- * @param unknown_type $request
137
- * @return string
138
- */
139
- protected function _handleRequest($request)
140
- {
141
- switch ($request) {
142
- case 'factfinder_proxy_scic':
143
- $this->_getFacade()->getScicAdapter()->setupTrackingFromRequest();
144
- return $this->_getFacade()->applyScicTracking();
145
- break;
146
-
147
- case 'factfinder_proxy_tracking':
148
- if ($this->_config['ffversion'] <= 69) {
149
- $this->_getFacade()->getLegacyTrackingAdapter()->setupTrackingFromRequest();
150
- return $this->_getFacade()->applyLegacyTracking();
151
- } else {
152
- $this->_getFacade()->getTrackingAdapter()->setupTrackingFromRequest();
153
- return $this->_getFacade()->applyTracking();
154
- }
155
- break;
156
-
157
- case 'factfinder_proxy_suggest':
158
- $handler = new Flagbit_FactFinder_Model_Handler_Suggest(
159
- $this->_getRequestParam('query'),
160
- $this->_getRequestParam('jquery_callback'),
161
- $this->_getFacade());
162
- return $handler->getSuggestions();
163
- break;
164
- }
165
- }
166
-
167
- /**
168
- * get Request Param by Key
169
- *
170
- * @param unknown_type $key
171
- * @return string
172
- */
173
- protected function _getRequestParam($key)
174
- {
175
- $value = null;
176
- if(isset($_REQUEST[$key])){
177
- $value = $_REQUEST[$key];
178
- }
179
- return $value;
180
- }
181
-
182
- /**
183
- * Return current page base url
184
- *
185
- * @return string
186
- */
187
- protected function _getFullPageUrl()
188
- {
189
- $uri = false;
190
- /**
191
- * Define server HTTP HOST
192
- */
193
- if (isset($_SERVER['HTTP_HOST'])) {
194
- $uri = $_SERVER['HTTP_HOST'];
195
- } elseif (isset($_SERVER['SERVER_NAME'])) {
196
- $uri = $_SERVER['SERVER_NAME'];
197
- }
198
-
199
- /**
200
- * Define request URI
201
- */
202
- if ($uri) {
203
- if (isset($_SERVER['REQUEST_URI'])) {
204
- $uri.= $_SERVER['REQUEST_URI'];
205
- } elseif (!empty($_SERVER['IIS_WasUrlRewritten']) && !empty($_SERVER['UNENCODED_URL'])) {
206
- $uri.= $_SERVER['UNENCODED_URL'];
207
- } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
208
- $uri.= $_SERVER['ORIG_PATH_INFO'];
209
- if (!empty($_SERVER['QUERY_STRING'])) {
210
- $uri.= $_SERVER['QUERY_STRING'];
211
- }
212
- }
213
- }
214
-
215
- $pieces = explode('?', $uri);
216
- $uri = array_shift($pieces);
217
-
218
- return $uri;
219
- }
220
-
221
- /**
222
- * Prepare page identifier
223
- *
224
- * @param string $id
225
- * @return string
226
- */
227
- public function prepareCacheId($id)
228
- {
229
- return self::REQUEST_ID_PREFIX . md5($id);
230
- }
231
-
232
- /**
233
- * Get HTTP request identifier
234
- *
235
- * @return string
236
- */
237
- public function getRequestId()
238
- {
239
- return $this->_requestId . (isset($_COOKIE['store']) ? $_COOKIE['store'] : '');
240
- }
241
-
242
- /**
243
- * Get page identifier for loading page from cache
244
- * @return string
245
- */
246
- public function getRequestCacheId()
247
- {
248
- return $this->_requestCacheId;
249
- }
250
-
251
- /**
252
- * Check if processor is allowed for current HTTP request.
253
- * Disable processing HTTPS requests and requests with "NO_CACHE" cookie
254
- *
255
- * @return bool
256
- */
257
- public function isAllowed()
258
- {
259
- if (!$this->_requestId) {
260
- return false;
261
- }
262
- if (isset($_COOKIE['NO_CACHE'])) {
263
- return false;
264
- }
265
- if (isset($_GET['no_cache'])) {
266
- return false;
267
- }
268
-
269
- return true;
270
- }
271
-
272
- /**
273
- * Get cache request associated tags
274
- * @return array
275
- */
276
- public function getRequestTags()
277
- {
278
- return $this->_requestTags;
279
- }
280
-
281
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/Scic/Queue.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Queue for SCIC orders. Orders are sent to FACT-Finder asynchronously by cronjobs.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
- class Flagbit_FactFinder_Model_Scic_Queue extends Mage_Core_Model_Abstract
22
- {
23
- public function _construct()
24
- {
25
- $this->_init('factfinder/scic_queue');
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Backend/Attributes.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- /**
3
- * Magento
4
- *
5
- * NOTICE OF LICENSE
6
- *
7
- * This source file is subject to the Open Software License (OSL 3.0)
8
- * that is bundled with this package in the file LICENSE.txt.
9
- * It is also available through the world-wide-web at this URL:
10
- * http://opensource.org/licenses/osl-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 Mage
22
- * @package Mage_CatalogInventory
23
- * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
- */
26
-
27
- /**
28
- * Backend for serialized array data
29
- *
30
- */
31
- class Flagbit_FactFinder_Model_System_Config_Backend_Attributes extends Mage_Core_Model_Config_Data
32
- {
33
- /**
34
- * Process data after load
35
- */
36
- protected function _afterLoad()
37
- {
38
- $value = $this->getValue();
39
- $value = Mage::helper('factfinder/backend')->makeArrayFieldValue($value);
40
- $this->setValue($value);
41
- }
42
-
43
- /**
44
- * Prepare data before save
45
- */
46
- protected function _beforeSave()
47
- {
48
- $value = $this->getValue();
49
- $value = Mage::helper('factfinder/backend')->makeStorableArrayFieldValue($value);
50
- $this->setValue($value);
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Backend/Enabled.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * Status Enabled Config Field Backend
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_System_Config_Backend_Enabled extends Mage_Core_Model_Config_Data {
22
-
23
- /**
24
- * Check request for errors found by Helper and Observer. It will print error messages if errors found and
25
- * in that case set value to 0.
26
- *
27
- * @return Flagbit_FactFinder_Model_System_Config_Backend_Enabled
28
- */
29
- protected function _beforeSave()
30
- {
31
- if (!$this->getValue()) {
32
- return $this;
33
- }
34
-
35
- $groups = Mage::app()->getRequest()->getPost('groups');
36
- if (isset($groups['search']['fields']['enabled']['errors'])) {
37
- $errors = $groups['search']['fields']['enabled']['errors'];
38
- if (is_array($errors)) {
39
- Mage::getSingleton('adminhtml/session')->addError(Mage::helper('factfinder')->__('FACT-Finder cannot be activated:').' <br/>'. implode('<br/>', $errors));
40
- }
41
- elseif (is_string($errors)) {
42
- Mage::getSingleton('adminhtml/session')->addError(Mage::helper('factfinder')->__('FACT-Finder cannot be activated:').' <br/>' . $errors);
43
- }
44
- else {
45
- Mage::getSingleton('adminhtml/session')->addError(Mage::helper('factfinder')->__('FACT-Finder cannot be activated:'));
46
- }
47
- $this->setValue('0');
48
- }
49
- else {
50
- Mage::app()->cleanCache(array(Flagbit_FactFinder_Model_Processor::CACHE_TAG));
51
- }
52
-
53
- return $this;
54
- }
55
-
56
-
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Authtype.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * provides Authtype Options
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_System_Config_Source_Authtype
22
- {
23
- /**
24
- * get Authtypes as Option Array
25
- *
26
- * @return array
27
- */
28
- public function toOptionArray()
29
- {
30
- return array(
31
- array(
32
- 'value' => 'http',
33
- 'label' => Mage::helper('factfinder')->__('http')
34
- ),
35
- array(
36
- 'value' => 'simple',
37
- 'label' => Mage::helper('factfinder')->__('simple')
38
- ),
39
- array(
40
- 'value' => 'advanced',
41
- 'label' => Mage::helper('factfinder')->__('advanced')
42
- )
43
- );
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Ffversion.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * provides FACT-Finder version options
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_System_Config_Source_Ffversion
22
- {
23
- /**
24
- * get FACT-Finder versions as Option Array
25
- *
26
- * @return array
27
- */
28
- public function toOptionArray()
29
- {
30
- return array(
31
- array(
32
- 'value' => 69,
33
- 'label' => '6.9'
34
- ),
35
- array(
36
- 'value' => 68,
37
- 'label' => '6.8'
38
- ),
39
- array(
40
- 'value' => 67,
41
- 'label' => '6.7'
42
- ),
43
- array(
44
- 'value' => 66,
45
- 'label' => '6.6'
46
- ),
47
- array(
48
- 'value' => 65,
49
- 'label' => '6.5'
50
- )
51
- );
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Identifier.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Model class
12
- *
13
- * provides Identifier Options
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Model_System_Config_Source_Identifier
22
- {
23
- /**
24
- * get Authtypes as Option Array
25
- *
26
- * @return array
27
- */
28
- public function toOptionArray()
29
- {
30
- return array(
31
- array(
32
- 'value' => 'entity_id',
33
- 'label' => Mage::helper('factfinder')->__('Product ID (default)')
34
- ),
35
- array(
36
- 'value' => 'sku',
37
- 'label' => Mage::helper('factfinder')->__('Product SKU')
38
- )
39
- );
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/Model/System/Config/Source/Imagetype.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Image type source model
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Francesco Marangi <f.marangi@mzentrale.de>
17
- * @version $Id$
18
- */
19
- class Flagbit_FactFinder_Model_System_Config_Source_Imagetype
20
- {
21
- /**
22
- * Get available image types
23
- *
24
- * @return array
25
- */
26
- public function toOptionArray()
27
- {
28
- $options = array();
29
- foreach (Mage::getModel('catalog/product')->getMediaAttributes() as $key => $value) {
30
- $options[] = array(
31
- 'label' => $value->getFrontendLabel(),
32
- 'value' => $key
33
- );
34
- }
35
- return $options;
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/controllers/Adminhtml/Factfinder/CockpitController.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Black class
12
- *
13
- * This Block class provides the FACT-Finder Business User Cockpit Authentication URL
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- class Flagbit_FactFinder_Adminhtml_Factfinder_CockpitController extends Mage_Adminhtml_Controller_Action
22
- {
23
-
24
- /**
25
- * Load layout, set active menu and breadcrumbs
26
- *
27
- * @return Mage_Widget_Adminhtml_Widget_InstanceController
28
- */
29
- protected function _initAction()
30
- {
31
- $this->loadLayout()
32
- ->_setActiveMenu('catalog/factfinder_cockpit')
33
- ->_addBreadcrumb(Mage::helper('factfinder')->__('Catalog'),
34
- Mage::helper('factfinder')->__('Catalog'))
35
- ->_addBreadcrumb(Mage::helper('factfinder')->__('FACT-Finder Business User Cockpit'),
36
- Mage::helper('factfinder')->__('FACT-Finder Business User Cockpit'));
37
- return $this;
38
- }
39
-
40
- /**
41
- * FACT-Finder Business User Cockpit Action
42
- */
43
- public function indexAction()
44
- {
45
- $this->_title($this->__('factfinder'))->_title($this->__('FACT-Finder Business User Cockpit'));
46
-
47
- $this->_initAction()
48
- ->renderLayout();
49
- }
50
-
51
-
52
-
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/controllers/ExportController.php DELETED
@@ -1,141 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Controller class
12
- *
13
- * This class the Export Controller
14
- * It provides a Products, Prices and Stocks Export
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Joerg Weller <weller@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_ExportController extends Mage_Core_Controller_Front_Action {
23
-
24
- const XML_AUTH_PASSWORD_PATH = 'factfinder/search/auth_password';
25
-
26
- /**
27
- * handle Export Authentification
28
- *
29
- * @return Mage_Core_Controller_Varien_Action
30
- */
31
- public function preDispatch()
32
- {
33
- $this->_getStoreId();
34
- $password = md5(Mage::getStoreConfig(self::XML_AUTH_PASSWORD_PATH));
35
-
36
- if ($password == '' || $password != $this->getRequest()->getParam('key')) {
37
- $this->setFlag('', self::FLAG_NO_DISPATCH, true);
38
- }
39
-
40
- return parent::preDispatch();
41
- }
42
-
43
- /**
44
- * get current Store ID
45
- *
46
- * @return int
47
- */
48
- protected function _getStoreId()
49
- {
50
- if ($storeId = $this->getRequest()->getParam('store')) {
51
- Mage::app()->setCurrentStore($storeId);
52
- }
53
-
54
- return Mage::app()->getStore()->getId();
55
- }
56
-
57
- /**
58
- * Initialize Product Export
59
- */
60
- public function productAction()
61
- {
62
- try
63
- {
64
- $this->lockSemaphore();
65
- }
66
- catch(RuntimeException $e)
67
- {
68
- // TODO: use a proper template
69
- echo
70
- '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
71
- '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">',
72
- '<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head>',
73
- '<body>',
74
- $this->__('Another export is already running. Please wait for it to finish before you start a new export.'), "<br>\n",
75
- $this->__('If you receive this message after another export has failed, please delete the file "ffexport.lock" within your Magento directory.'),
76
- '</body></html>';
77
- flush();
78
- return;
79
- }
80
-
81
- try {
82
- $exportModel = Mage::getModel('factfinder/export_product');
83
- $exportModel->doExport(
84
- $this->_getStoreId()
85
- );
86
- $this->releaseSemaphore(); // finally-workaround
87
- } catch(Exception $e) {
88
- $this->releaseSemaphore(); // finally-workaround
89
- throw $e;
90
- }
91
- }
92
-
93
- /**
94
- * Initialize Price Export
95
- */
96
- public function priceAction()
97
- {
98
- $exportModel = Mage::getModel('factfinder/export_price');
99
- $exportModel->doExport(
100
- $this->_getStoreId()
101
- );
102
- }
103
-
104
- /**
105
- * Initialize Stock Export
106
- */
107
- public function stockAction()
108
- {
109
- $exportModel = Mage::getModel('factfinder/export_stock');
110
- $exportModel->doExport(
111
- $this->_getStoreId()
112
- );
113
- }
114
-
115
- /**
116
- * Locks the semaphore
117
- * Throws an exception, if semaphore is already locked
118
- **/
119
- protected function lockSemaphore()
120
- {
121
- $mtime = @filemtime($this->_getLockFileName());
122
- if($mtime && time() - $mtime < FF::getSingleton('configuration')->getSemaphoreTimeout())
123
- {
124
- throw new RuntimeException();
125
- }
126
- @touch($this->_getLockFileName());
127
- }
128
-
129
- /**
130
- * Release the semaphore
131
- **/
132
- protected function releaseSemaphore()
133
- {
134
- @unlink($this->_getLockFileName());
135
- }
136
-
137
- protected function _getLockFileName()
138
- {
139
- return "ffexport_".$this->_getStoreId().".lock";
140
- }
141
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/controllers/ProxyController.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Controller class
12
- *
13
- * This class the Proxy Controller
14
- * It provides a scic and a suggest Action
15
- *
16
- * @category Mage
17
- * @package Flagbit_FactFinder
18
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
19
- * @author Joerg Weller <weller@flagbit.de>
20
- * @version $Id$
21
- */
22
- class Flagbit_FactFinder_ProxyController extends Mage_Core_Controller_Front_Action {
23
-
24
- /**
25
- * tracking Action
26
- */
27
- public function trackingAction()
28
- {
29
- $this->getResponse()->setBody(
30
- Mage::getModel('factfinder/processor')->handleInAppRequest($this->getFullActionName())
31
- );
32
- }
33
-
34
- /**
35
- * scic Action
36
- */
37
- public function scicAction()
38
- {
39
- $this->trackingAction();
40
- }
41
-
42
- /**
43
- * suggest Action
44
- */
45
- public function suggestAction()
46
- {
47
- $this->getResponse()->setHeader("Content-Type:", "text/javascript;charset=utf-8", true);
48
- $this->getResponse()->setBody(
49
- Mage::getModel('factfinder/processor')->handleInAppRequest($this->getFullActionName())
50
- );
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/etc/adminhtml.xml DELETED
@@ -1,49 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * Module Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
- <config>
22
- <acl>
23
- <resources>
24
- <admin>
25
- <children>
26
- <catalog>
27
- <children>
28
- <factfinder_cockpit translate="title" module="factfinder">
29
- <title>FACT-Finder Business User Cockpit</title>
30
- <sort_order>35</sort_order>
31
- </factfinder_cockpit>
32
- </children>
33
- </catalog>
34
- </children>
35
- </admin>
36
- </resources>
37
- </acl>
38
- <menu>
39
- <catalog>
40
- <children>
41
- <factfinder_cockpit translate="title" module="factfinder">
42
- <title>FACT-Finder Business User Cockpit</title>
43
- <sort_order>35</sort_order>
44
- <action>adminhtml/factfinder_cockpit</action>
45
- </factfinder_cockpit>
46
- </children>
47
- </catalog>
48
- </menu>
49
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/etc/config.xml DELETED
@@ -1,313 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * Module Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
- <config>
22
- <modules>
23
- <Flagbit_FactFinder>
24
- <active>true</active>
25
- <version>3.5.5</version>
26
- </Flagbit_FactFinder>
27
- </modules>
28
- <global>
29
- <helpers>
30
- <factfinder>
31
- <class>Flagbit_FactFinder_Helper</class>
32
- </factfinder>
33
- </helpers>
34
- <blocks>
35
- <factfinder>
36
- <class>Flagbit_FactFinder_Block</class>
37
- </factfinder>
38
- <catalogsearch>
39
- <rewrite>
40
- <term>Flagbit_FactFinder_Block_TagCloud</term>
41
- <layer>Flagbit_FactFinder_Block_Layer</layer>
42
- </rewrite>
43
- </catalogsearch>
44
- <catalog>
45
- <rewrite>
46
- <layer_view>Flagbit_FactFinder_Block_Layer</layer_view>
47
- <product_list_upsell>Flagbit_FactFinder_Block_Product_List_Upsell</product_list_upsell>
48
- <product_list_crosssell>Flagbit_FactFinder_Block_Product_List_Crosssell</product_list_crosssell>
49
- </rewrite>
50
- </catalog>
51
- <checkout>
52
- <rewrite>
53
- <cart_crosssell>Flagbit_FactFinder_Block_Cart_Crosssell</cart_crosssell>
54
- </rewrite>
55
- </checkout>
56
- <enterprise_search>
57
- <rewrite>
58
- <catalogsearch_layer>Flagbit_FactFinder_Block_Layer</catalogsearch_layer>
59
- <catalog_layer_view>Flagbit_FactFinder_Block_Layer</catalog_layer_view>
60
- </rewrite>
61
- </enterprise_search>
62
- <xmlconnect>
63
- <rewrite>
64
- <catalog_search>Flagbit_FactFinder_Block_XmlConnect_Catalog_Search</catalog_search>
65
- <catalog_search_suggest>Flagbit_FactFinder_Block_XmlConnect_Catalog_Search_Suggest</catalog_search_suggest>
66
- <catalog_product_list>Flagbit_FactFinder_Block_XmlConnect_Catalog_Product_List</catalog_product_list>
67
- </rewrite>
68
- </xmlconnect>
69
- </blocks>
70
- <models>
71
- <factfinder>
72
- <class>Flagbit_FactFinder_Model</class>
73
- <resourceModel>factfinder_mysql4</resourceModel>
74
- </factfinder>
75
- <factfinder_mysql4>
76
- <class>Flagbit_FactFinder_Model_Mysql4</class>
77
- <entities>
78
- <scic_queue><table>flagbit_factfinder_scic_queue</table></scic_queue>
79
- </entities>
80
- </factfinder_mysql4>
81
- <catalogsearch>
82
- <rewrite>
83
- <layer>Flagbit_FactFinder_Model_Layer</layer>
84
- <layer_filter_attribute>Flagbit_FactFinder_Model_Layer_Filter_Attribute_Catalogsearch</layer_filter_attribute>
85
- </rewrite>
86
- </catalogsearch>
87
- <catalog>
88
- <rewrite>
89
- <layer>Flagbit_FactFinder_Model_Layer</layer>
90
- <layer_filter_attribute>Flagbit_FactFinder_Model_Layer_Filter_Attribute_Catalog</layer_filter_attribute>
91
- </rewrite>
92
- </catalog>
93
- </models>
94
- <resources>
95
- <factfinder_setup>
96
- <setup>
97
- <module>Flagbit_FactFinder</module>
98
- </setup>
99
- <connection>
100
- <use>core_setup</use>
101
- </connection>
102
- </factfinder_setup>
103
- </resources>
104
- <events>
105
- <controller_action_predispatch_adminhtml_system_config_save>
106
- <observers>
107
- <setEnabledFlagInFactFinderConfig>
108
- <class>factfinder/observer</class>
109
- <method>setEnabledFlagInFactFinderConfig</method>
110
- </setEnabledFlagInFactFinderConfig>
111
- </observers>
112
- </controller_action_predispatch_adminhtml_system_config_save>
113
- </events>
114
- <cache>
115
- <types>
116
- <factfinder_search translate="label,description" module="factfinder">
117
- <label>FACT-Finder</label>
118
- <description>Search Request Cache (won't work with PHP 5.2 or less)</description>
119
- <tags>FACTFINDER_SEARCH</tags>
120
- </factfinder_search>
121
- </types>
122
- </cache>
123
- </global>
124
- <frontend>
125
- <layout>
126
- <updates>
127
- <factfinder>
128
- <file>factfinder.xml</file>
129
- </factfinder>
130
- </updates>
131
- </layout>
132
- <routers>
133
- <factfinder>
134
- <use>standard</use>
135
- <args>
136
- <module>Flagbit_FactFinder</module>
137
- <frontName>factfinder</frontName>
138
- </args>
139
- </factfinder>
140
- </routers>
141
- <events>
142
- <checkout_cart_product_add_after>
143
- <observers>
144
- <addToCartSendSCIC>
145
- <class>factfinder/observer</class>
146
- <method>addToCartSendSCIC</method>
147
- </addToCartSendSCIC>
148
- </observers>
149
- </checkout_cart_product_add_after>
150
- <sales_order_place_after>
151
- <observers>
152
- <addOrderDetailsToSCICQueue>
153
- <class>factfinder/observer</class>
154
- <method>addOrderDetailsToSCICQueue</method>
155
- </addOrderDetailsToSCICQueue>
156
- </observers>
157
- </sales_order_place_after>
158
- <controller_action_layout_load_before>
159
- <observers>
160
- <addActivationLayoutHandles>
161
- <class>factfinder/observer</class>
162
- <method>addActivationLayoutHandles</method>
163
- </addActivationLayoutHandles>
164
- </observers>
165
- </controller_action_layout_load_before>
166
- <controller_action_layout_generate_blocks_after>
167
- <observers>
168
- <initializeAfterSearchNavigation>
169
- <class>factfinder/observer</class>
170
- <method>initializeAfterSearchNavigation</method>
171
- </initializeAfterSearchNavigation>
172
- <handleRedirects>
173
- <class>factfinder/observer</class>
174
- <method>handleRedirects</method>
175
- </handleRedirects>
176
- </observers>
177
- </controller_action_layout_generate_blocks_after>
178
- </events>
179
- <translate>
180
- <modules>
181
- <Flagbit_FactFinder>
182
- <files>
183
- <default>Flagbit_FactFinder.csv</default>
184
- </files>
185
- </Flagbit_FactFinder>
186
- </modules>
187
- </translate>
188
- </frontend>
189
- <adminhtml>
190
- <acl>
191
- <resources>
192
- <admin>
193
- <children>
194
- <system>
195
- <children>
196
- <config>
197
- <children>
198
- <factfinder>
199
- <title>FACT-Finder</title>
200
- </factfinder>
201
- </children>
202
- </config>
203
- </children>
204
- </system>
205
- </children>
206
- </admin>
207
- </resources>
208
- </acl>
209
- <translate>
210
- <modules>
211
- <Flagbit_FactFinder>
212
- <files>
213
- <default>Flagbit_FactFinder.csv</default>
214
- </files>
215
- </Flagbit_FactFinder>
216
- </modules>
217
- </translate>
218
- <layout>
219
- <updates>
220
- <factfinder>
221
- <file>factfinder.xml</file>
222
- </factfinder>
223
- </updates>
224
- </layout>
225
- <events>
226
- <core_block_abstract_to_html_after>
227
- <observers>
228
- <rewriteBackendMenuHtmlForCockpitRedirect>
229
- <class>factfinder/observer</class>
230
- <method>rewriteBackendMenuHtmlForCockpitRedirect</method>
231
- </rewriteBackendMenuHtmlForCockpitRedirect>
232
- </observers>
233
- </core_block_abstract_to_html_after>
234
- </events>
235
- </adminhtml>
236
- <admin>
237
- <routers>
238
- <adminhtml>
239
- <args>
240
- <modules>
241
- <factfinder before="Mage_Adminhtml">Flagbit_FactFinder_Adminhtml</factfinder>
242
- </modules>
243
- </args>
244
- </adminhtml>
245
- </routers>
246
- </admin>
247
- <crontab>
248
- <jobs>
249
- <factfinder_scic_queue_processing>
250
- <schedule><cron_expr>* * * * *</cron_expr></schedule>
251
- <run><model>factfinder/observer::processScicOrderQueue</model></run>
252
- </factfinder_scic_queue_processing>
253
- </jobs>
254
- </crontab>
255
- <default>
256
- <catalog>
257
- <search>
258
- <engine>factfinder/search_engine</engine>
259
- </search>
260
- </catalog>
261
- <factfinder>
262
- <version>3.5.5</version>
263
- <revision>$Rev: 25896 $</revision>
264
- <debug>false</debug>
265
-
266
- <!-- search settings: WARNING: dont change settings here, please use the Magento backoffice ...
267
- if you still have to change something here, dont forget to clear the configuration cache -->
268
- <search>
269
- <address>example.com</address>
270
- <port>80</port>
271
- <protocol>http</protocol> <!-- possible values: http, https -->
272
-
273
- <ffversion>68</ffversion>
274
-
275
- <auth_user></auth_user>
276
- <auth_password></auth_password>
277
- <auth_type>advanced</auth_type> <!-- possible values: http (for FF <= 6.4); simple | advanced (for FF >= 6.5)-->
278
- <auth_advancedPrefix>FACT-FINDER</auth_advancedPrefix>
279
- <auth_advancedPostfix>FACT-FINDER</auth_advancedPostfix>
280
-
281
- <context></context>
282
- <channel></channel>
283
- <language></language>
284
- </search>
285
- <fallback>
286
- <use_fallback>0</use_fallback>
287
- <wait_time>15</wait_time>
288
- </fallback>
289
- <export>
290
- <urls>0</urls>
291
- <suggest_image_size>40</suggest_image_size>
292
- <suggest_image_type>image</suggest_image_type>
293
- <track_carts>1</track_carts>
294
- <track_checkout>1</track_checkout>
295
- </export>
296
- <config>
297
- <identifier>entity_id</identifier>
298
- <proxy>0</proxy>
299
- <debug>0</debug>
300
- <navigation>0</navigation>
301
- <upsell>0</upsell>
302
- <crosssell>0</crosssell>
303
- </config>
304
-
305
- <!-- encoding settings -->
306
- <encoding>
307
- <pageContent>UTF-8</pageContent>
308
- <serverURI>UTF-8</serverURI>
309
- <pageURI>UTF-8</pageURI>
310
- </encoding>
311
- </factfinder>
312
- </default>
313
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-install-3.2.0.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Install script
12
- *
13
- * Install script for SCIC queue. Orders are sent to FACT-Finder asynchronously by cronjobs.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
-
22
- $installer = $this;
23
- $installer->startSetup();
24
-
25
- $installer->run("
26
- CREATE TABLE `{$installer->getTable('factfinder/scic_queue')}` (
27
- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
28
- `product_id` varchar(64) NOT NULL DEFAULT '',
29
- `sid` varchar(32) NOT NULL DEFAULT '',
30
- `userid` varchar(32) NOT NULL DEFAULT '',
31
- `price` decimal(12,4) NOT NULL default '0.0000',
32
- `count` smallint(5) unsigned NOT NULL default '1',
33
-
34
- PRIMARY KEY (`id`)
35
- ) ENGINE = InnoDB ;
36
- ");
37
-
38
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-upgrade-3.2.0-3.2.1.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Install script
12
- *
13
- * Install script for SCIC queue. Orders are sent to FACT-Finder asynchronously by cronjobs.
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
-
22
- $installer = $this;
23
- $installer->startSetup();
24
-
25
- $installer->run("
26
- ALTER TABLE `{$installer->getTable('factfinder/scic_queue')}`
27
- ADD COLUMN `store_id` INT(10) UNSIGNED NOT NULL DEFAULT '0';
28
- ");
29
-
30
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Flagbit/FactFinder/sql/factfinder_setup/mysql4-upgrade-3.2.1-3.3.0.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Install script
12
- *
13
- * Update configuration keys
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Michael Türk <tuerk@flagbit.de>
19
- * @version $Id: Processor.php 647 2011-03-21 10:32:14Z rudolf_batt $
20
- */
21
-
22
- $installer = $this;
23
- $installer->startSetup();
24
-
25
- $installer->run("
26
- UPDATE `{$installer->getTable('core/config_data')}`
27
- SET `path` = 'factfinder/activation/navigation' where `path` = 'factfinder/config/navigation';
28
- UPDATE `{$installer->getTable('core/config_data')}`
29
- SET `path` = 'factfinder/activation/upsell' where `path` = 'factfinder/config/upsell';
30
- UPDATE `{$installer->getTable('core/config_data')}`
31
- SET `path` = 'factfinder/activation/crosssell' where `path` = 'factfinder/config/crosssell';
32
- ");
33
-
34
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/layout/factfinder.xml DELETED
@@ -1,28 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * Module Layout Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
-
22
- <layout>
23
- <adminhtml_factfinder_cockpit_index>
24
- <reference name="content">
25
- <block type="factfinder/adminhtml_cockpit" name="factfinder_cockpit" template="factfinder/cockpit.phtml"/>
26
- </reference>
27
- </adminhtml_factfinder_cockpit_index>
28
- </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/factfinder/cockpit.phtml DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Template
12
- *
13
- * Business User Cockpit Template
14
- *
15
- * @category Mage
16
- * @package Flagbit_FactFinder
17
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
18
- * @author Joerg Weller <weller@flagbit.de>
19
- * @version $Id$
20
- */
21
- ?>
22
- <iframe src="<?php echo $this->getManagementUrl();?>" id="factfinder_cockpit_frame" style="width:100%; height:600px;" name="factfinder_cockpit_frame" scrolling="auto"></iframe>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/layout/factfinder.xml DELETED
@@ -1,78 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * Module Layout Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
- <layout version="0.1.0">
22
- <factfinder_suggest_enabled>
23
- <reference name="head">
24
- <action method="addJs"><script>factfinder/jXHR.js</script></action>
25
- <action method="addJs"><script>factfinder/suggest.js</script></action>
26
- <action method="addCss"><stylesheet>css/factfinder.css</stylesheet></action>
27
- </reference>
28
- </factfinder_suggest_enabled>
29
-
30
- <factfinder_suggest_version_lt67>
31
- <reference name="top.search">
32
- <action method="setTemplate"><template>factfinder/form.advancedsuggest.phtml</template></action>
33
- </reference>
34
- </factfinder_suggest_version_lt67>
35
-
36
- <factfinder_suggest_version_gt68>
37
- <reference name="top.search">
38
- <action method="setTemplate"><template>factfinder/form.advancedsuggest68.phtml</template></action>
39
- </reference>
40
- </factfinder_suggest_version_gt68>
41
-
42
- <catalogsearch_result_index>
43
- <reference name="content">
44
- <block type="factfinder/campaign_feedback" before="search.result" name="factfinder.campaign.feedback" template="factfinder/campaign/feedback.phtml">
45
- <action method="setTextNumber"><number>1</number></action>
46
- </block>
47
- <block type="factfinder/campaign_advisory" after="factfinder.campaign.feedback" name="factfinder.campaign.advisory" template="factfinder/campaign/advisory.phtml" />
48
- <block type="core/template" name="factfinder.logo" template="factfinder/logo.phtml"/>
49
- <block type="factfinder/secondaryresult" after="search.result" name="factfinder.secondaryresult" template="factfinder/secondaryresult.phtml" />
50
- </reference>
51
- </catalogsearch_result_index>
52
-
53
- <catalog_product_view>
54
- <reference name="content">
55
- <block type="factfinder/campaign_product_advisory" before="product.info" name="factfinder.campaign.advisory" template="factfinder/campaign/product/advisory.phtml" />
56
- <block type="factfinder/campaign_product_feedback" before="product.info" name="factfinder.campaign.feedback" template="factfinder/campaign/product/feedback.phtml" />
57
- </reference>
58
- <reference name="product.info.upsell">
59
- <action method="setItemLimit"><type>upsell</type><limit>20</limit></action>
60
- </reference>
61
- </catalog_product_view>
62
-
63
- <checkout_cart_index>
64
- <reference name="checkout.cart.form.before">
65
- <block type="factfinder/campaign_cart_advisory" before="-" name="factfinder.campaign.advisory" template="factfinder/campaign/cart/advisory.phtml" />
66
- <block type="factfinder/campaign_cart_feedback" before="-" name="factfinder.campaign.feedback" template="factfinder/campaign/cart/feedback.phtml" />
67
- </reference>
68
- </checkout_cart_index>
69
-
70
- <factfinder_clicktracking_enabled>
71
- <reference name="head">
72
- <action method="addJs"><script>factfinder/tracking.js</script></action>
73
- </reference>
74
- <reference name="content">
75
- <block type="factfinder/tracking" name="factfinder.tracking" template="factfinder/tracking.phtml"/>
76
- </reference>
77
- </factfinder_clicktracking_enabled>
78
- </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/layout/factfinder/asn.xml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Asn
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Asn
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <layout>
15
+
16
+ <catalogsearch_result_index>
17
+ <reference name="head">
18
+ <block type="core/template" name="ff_slider_script">
19
+ <action method="setTemplate"><template>factfinder/asn/layer/slider.phtml</template></action>
20
+ </block>
21
+ </reference>
22
+ </catalogsearch_result_index>
23
+
24
+ <catalog_category_layered>
25
+ <reference name="head">
26
+ <block type="core/template" name="ff_slider_script">
27
+ <action method="setTemplate"><template>factfinder/asn/layer/slider.phtml</template></action>
28
+ </block>
29
+ </reference>
30
+ <reference name="product_list">
31
+ <block type="factfinder_asn/catalog_product_list_toolbar" name="factfinder_product_list_toolbar" template="catalog/product/list/toolbar.phtml">
32
+ <block type="factfinder_asn/catalog_product_pager" name="product_list_toolbar_pager"/>
33
+ </block>
34
+ <action method="setToolbarBlockName"><name>factfinder_product_list_toolbar</name></action>
35
+ </reference>
36
+ </catalog_category_layered>
37
+
38
+ </layout>
app/design/frontend/base/default/layout/factfinder/campaigns.xml ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Campaigns
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Campaigns
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ */
13
+ -->
14
+ <layout>
15
+
16
+ <catalogsearch_result_index>
17
+
18
+ <reference name="content">
19
+ <block type="factfinder_campaigns/advisory_search" name="ff.search.advisory" before="-" template="factfinder/campaigns/advisory.phtml" />
20
+ <!-- pushed products -->
21
+ <block type="factfinder_campaigns/pushed_search" name="search.pushed" before="search.result">
22
+ <action method="setMaxColNum"><num>3</num></action>
23
+ <block type="factfinder_campaigns/feedback_search" before="-" name="ff.feedback.above.pushed" as="feedback_above">
24
+ <action method="setLabel"><label>above pushed product</label></action>
25
+ </block>
26
+ <block type="factfinder_campaigns/feedback_search" after="-" name="ff.feedback.below.pushed" as="feedback_below">
27
+ <action method="setLabel"><label>below pushed product</label></action>
28
+ </block>
29
+ </block>
30
+
31
+ <!-- above and below search result labels-->
32
+ <block type="factfinder_campaigns/feedback_search" before="search.result" name="ff.feedback.search.above" as="search_above">
33
+ <action method="setLabel"><label>above search result</label></action>
34
+ </block>
35
+ <block type="factfinder_campaigns/feedback_search" after="search.result" name="ff.feedback.search.below" as="search_below">
36
+ <action method="setLabel"><label>below search result</label></action>
37
+ </block>
38
+
39
+ </reference>
40
+
41
+ <!-- above and below asn labels-->
42
+ <reference name="left_first">
43
+ <block type="factfinder_campaigns/feedback_search" before="-" name="ff.feedback.above.asn" as="feedback_above_asn">
44
+ <action method="setLabel"><label>above asn</label></action>
45
+ </block>
46
+ <block type="factfinder_campaigns/feedback_search" after="-" name="ff.feedback.below.asn" as="feedback_below_asn">
47
+ <action method="setLabel"><label>below asn</label></action>
48
+ </block>
49
+ </reference>
50
+ </catalogsearch_result_index>
51
+
52
+ <catalog_category_view>
53
+ <reference name="content">
54
+ <block type="factfinder_campaigns/advisory_search" name="ff.search.advisory" before="-" template="factfinder/campaigns/advisory.phtml" />
55
+ <!-- pushed products -->
56
+ <block type="factfinder_campaigns/pushed_search" name="search.pushed" after="ff.search.advisory">
57
+ <action method="setMaxColNum"><num>3</num></action>
58
+ <block type="factfinder_campaigns/feedback_search" before="-" name="ff.feedback.above.pushed" as="feedback_above">
59
+ <action method="setLabel"><label>above pushed product</label></action>
60
+ </block>
61
+ <block type="factfinder_campaigns/feedback_search" after="-" name="ff.feedback.below.pushed" as="feedback_below">
62
+ <action method="setLabel"><label>below pushed product</label></action>
63
+ </block>
64
+ </block>
65
+
66
+ <!-- above and below search result labels-->
67
+ <block type="factfinder_campaigns/feedback_search" after="product_list" name="ff.feedback.search.above" as="search_above">
68
+ <action method="setLabel"><label>above search result</label></action>
69
+ </block>
70
+ <block type="factfinder_campaigns/feedback_search" after="category.products" name="ff.feedback.search.below" as="search_below">
71
+ <action method="setLabel"><label>below search result</label></action>
72
+ </block>
73
+ </reference>
74
+
75
+ <!-- above and below asn labels-->
76
+ <reference name="left_first">
77
+ <block type="factfinder_campaigns/feedback_search" before="-" name="ff.feedback.above.asn" as="feedback_above_asn">
78
+ <action method="setLabel"><label>above asn</label></action>
79
+ </block>
80
+ </reference>
81
+ <reference name="left">
82
+ <block type="factfinder_campaigns/feedback_search" after="-" name="ff.feedback.below.asn" as="feedback_below_asn">
83
+ <action method="setLabel"><label>below asn</label></action>
84
+ </block>
85
+ </reference>
86
+ </catalog_category_view>
87
+
88
+
89
+ <checkout_cart_index>
90
+ <reference name="content">
91
+ <!-- Pushed products -->
92
+ <block type="factfinder_campaigns/pushed_cart" name="ff.pushed.products" as="pushed_products" before="-">
93
+ <action method="setMaxColNum"><num>6</num></action>
94
+ <block type="factfinder_campaigns/feedback_cart" before="-" name="ff.feedback.above.pushed" as="feedback_above">
95
+ <action method="setLabel"><label>above pushed product</label></action>
96
+ </block>
97
+ <block type="factfinder_campaigns/feedback_cart" after="-" name="ff.feedback.below.pushed" as="feedback_below">
98
+ <action method="setLabel"><label>below pushed product</label></action>
99
+ </block>
100
+ </block>
101
+ </reference>
102
+ </checkout_cart_index>
103
+
104
+
105
+ <catalog_product_view>
106
+ <!-- Pushed products -->
107
+ <reference name="content">
108
+ <block type="factfinder_campaigns/pushed_product" name="factfinder.pushed.product">
109
+ <action method="setMaxColNum"><num>6</num></action>
110
+ <block type="factfinder_campaigns/feedback_product" before="-" name="ff.feedback.above.pushed" as="feedback_above">
111
+ <action method="setLabel"><label>above pushed product</label></action>
112
+ </block>
113
+ <block type="factfinder_campaigns/feedback_product" after="-" name="ff.feedback.below.pushed" as="feedback_below">
114
+ <action method="setLabel"><label>below pushed product</label></action>
115
+ </block>
116
+ </block>
117
+ </reference>
118
+ </catalog_product_view>
119
+
120
+ </layout>
app/design/frontend/base/default/layout/factfinder/core.xml ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Core
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Core
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <layout>
16
+
17
+ <factfinder_export_default>
18
+ <reference name="root">
19
+ <action method="setTemplate"><template>page/empty.phtml</template></action>
20
+ <block type="core/template" name="content"/>
21
+ </reference>
22
+ </factfinder_export_default>
23
+
24
+ <factfinder_export_export>
25
+ <update handle="factfinder_export_default" />
26
+ <reference name="content">
27
+ <action method="setTemplate"><template>factfinder/core/export/locked.phtml</template></action>
28
+ </reference>
29
+ </factfinder_export_export>
30
+
31
+ <factfinder_export_get>
32
+ <update handle="factfinder_export_default" />
33
+ <reference name="content">
34
+ <action method="setTemplate"><template>factfinder/core/export/locked.phtml</template></action>
35
+ </reference>
36
+ </factfinder_export_get>
37
+
38
+ <factfinder_export_download>
39
+ <update handle="factfinder_export_default" />
40
+ <reference name="content">
41
+ <action method="setTemplate"><template>factfinder/core/export/nofile.phtml</template></action>
42
+ </reference>
43
+ </factfinder_export_download>
44
+
45
+ <catalogsearch_result_index>
46
+ <reference name="search_result_list">
47
+ <block type="factfinder/catalog_product_list_toolbar" name="factfinder_product_list_toolbar" template="catalog/product/list/toolbar.phtml">
48
+ <block type="factfinder/catalog_product_pager" name="product_list_toolbar_pager"/>
49
+ </block>
50
+ <action method="setToolbarBlockName"><name>factfinder_product_list_toolbar</name></action>
51
+ </reference>
52
+ </catalogsearch_result_index>
53
+
54
+ </layout>
app/design/frontend/base/default/layout/factfinder/suggest.xml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Suggest
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Suggest
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <layout>
16
+
17
+ <factfinder_suggest_enabled>
18
+ <reference name="head">
19
+ <action method="addJs"><script>factfinder/jXHR.js</script></action>
20
+ <action method="addJs"><script>factfinder/suggest.js</script></action>
21
+ <action method="addCss"><stylesheet>css/factfinder_suggest.css</stylesheet></action>
22
+ </reference>
23
+ <reference name="header">
24
+ <block type="factfinder_suggest/topSearch" name="top.search" as="topSearch" template="factfinder/suggest/advancedsuggest.phtml"/>
25
+ </reference>
26
+ </factfinder_suggest_enabled>
27
+
28
+ </layout>
app/design/frontend/base/default/layout/factfinder/tagcloud.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_TagCloud
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_TagCloud
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <layout>
16
+ <catalogsearch_result_index>
17
+ <reference name="content">
18
+ <block type="factfinder_tagcloud/tagCloud" name="factfinder.tagcloud" template="catalogsearch/term.phtml"/>
19
+ </reference>
20
+ </catalogsearch_result_index>
21
+ </layout>
app/design/frontend/base/default/layout/factfinder/tracking.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * FACTFinder_Tracking
5
+ *
6
+ * @category Mage
7
+ * @package FACTFinder_Tracking
8
+ * @author Flagbit Magento Team <magento@flagbit.de>
9
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
10
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
+ * @link http://www.flagbit.de
12
+ *
13
+ */
14
+ -->
15
+ <layout>
16
+ <factfinder_clicktracking_enabled>
17
+ <reference name="head">
18
+ <action method="addJs"><script>factfinder/tracking.js</script></action>
19
+ </reference>
20
+ <reference name="content">
21
+ <block type="factfinder_tracking/init" name="factfinder.tracking" template="factfinder/tracking/init.phtml"/>
22
+ </reference>
23
+ </factfinder_clicktracking_enabled>
24
+ </layout>
app/design/frontend/base/default/template/factfinder/asn/layer/filter/slider.phtml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+ /**
13
+ * Slider HTML Template
14
+ */
15
+ ?>
16
+ <ol style="margin: 10px;">
17
+ <?php foreach ($this->getItems() as $_item): ?>
18
+ <li>
19
+ <div id="<?php echo base64_encode($this->getData('requestVar')); ?>" style="width: 170px;padding:10px 0px;"></div>
20
+ <script type="text/javascript" language="javascript">
21
+ //<![CDATA[
22
+ Event.observe(document, 'ffslider:init', function(event){
23
+ oneTouchSlider.addSlider({
24
+ hostElementId:'<?php echo base64_encode($this->getData('requestVar'));?>',
25
+ leftBorder: <?php echo $this->getAbsoluteMin();?>,
26
+ rightBorder: <?php echo $this->getAbsoluteMax();?>,
27
+ currentLeft: <?php echo $this->getSelectedMin();?>,
28
+ currentRight: <?php echo $this->getSelectedMax();?>,
29
+ unit:"<?php echo $this->getUnit();?>",
30
+ callback:function(left, right){
31
+ var url = '<?php echo $_item->getUrl() ?>';
32
+ window.location.href= url.replace('%5BVALUE%5D',left + ' - ' + right);
33
+ }
34
+ });
35
+ }
36
+ );
37
+ //]]>
38
+ </script>
39
+ </li>
40
+ <?php endforeach ?>
41
+ </ol>
app/design/frontend/base/default/template/factfinder/asn/layer/slider.phtml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Asn
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Asn
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+ ?>
13
+ <script type="text/javascript" src="<?php echo $this->getSkinUrl('js/factfinder_onetouchslider/de.factfinder.asn.slider.OneTouchSlider.nocache.js'); ?>"></script>
14
+ <script type="text/javascript">
15
+ oneTouchSliderOnLoad = function() {
16
+ document.fire("ffslider:init");
17
+ }
18
+ </script>
app/design/frontend/base/default/template/factfinder/campaign/advisory.phtml DELETED
@@ -1,12 +0,0 @@
1
- <?php if ($questions = $this->getActiveQuestions()): ?>
2
- <?php foreach ($questions as $question): ?>
3
- <div class="factfinder-advisorCampaign">
4
- <p class="factfinder-advisorCampaign-question"><?php echo $question->getText() ?></p>
5
- <p>
6
- <?php foreach ($question->getAnswers() as $answer): ?>
7
- <a class="factfinder-advisorCampaign-answer" href="<?php echo $answer->getParams() ?>"><?php echo $answer->getText() ?></a>
8
- <?php endforeach; ?>
9
- </p>
10
- </div>
11
- <?php endforeach; ?>
12
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaign/cart/advisory.phtml DELETED
@@ -1,12 +0,0 @@
1
- <?php if ($questions = $this->getActiveQuestions()): ?>
2
- <?php foreach ($questions as $question): ?>
3
- <div class="factfinder-advisorCampaign">
4
- <p class="factfinder-advisorCampaign-question"><?php echo $question->getText() ?></p>
5
- <p>
6
- <?php foreach ($question->getAnswers() as $answer): ?>
7
- <a class="factfinder-advisorCampaign-answer" href="<?php echo $answer->getParams() ?>"><?php echo $answer->getText() ?></a>
8
- <?php endforeach; ?>
9
- </p>
10
- </div>
11
- <?php endforeach; ?>
12
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaign/cart/feedback.phtml DELETED
@@ -1,6 +0,0 @@
1
- <?php if ($feedback = $this->getActiveFeedback()): ?>
2
- <?php $feedbackIds = array(0,1); ?>
3
- <?php foreach ($feedbackIds as $feedbackId): ?>
4
- <p class="factfinder-feedbackCampaign"><?php echo $feedback->getFeedback($feedbackId) ?></p>
5
- <?php endforeach; ?>
6
- <?php endif; ?>
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaign/feedback.phtml DELETED
@@ -1,11 +0,0 @@
1
- <?php if(Mage::helper('factfinder/search')->getIsEnabled()):?>
2
- <div class="ffcampaigntext"><?php echo $this->getText(); ?></div>
3
-
4
- <?php
5
- // this is an example, how to use the pushed products
6
- $pushedProducts = $this->getPushedProductsCollection()->load()->toArray();
7
- if (!empty($pushedProducts)) {
8
- //customize here the pushed products output
9
- }
10
- ?>
11
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaign/product/advisory.phtml DELETED
@@ -1,13 +0,0 @@
1
- <!-- ff product advisory template -->
2
- <?php if ($questions = $this->getActiveQuestions()): ?>
3
- <?php foreach ($questions as $question): ?>
4
- <div class="factfinder-advisorCampaign">
5
- <p class="factfinder-advisorCampaign-question"><?php echo $question->getText() ?></p>
6
- <p>
7
- <?php foreach ($question->getAnswers() as $answer): ?>
8
- <a class="factfinder-advisorCampaign-answer" href="<?php echo $answer->getParams() ?>"><?php echo $answer->getText() ?></a>
9
- <?php endforeach; ?>
10
- </p>
11
- </div>
12
- <?php endforeach; ?>
13
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaign/product/feedback.phtml DELETED
@@ -1,7 +0,0 @@
1
- <!-- ff product feedback -->
2
- <?php if ($feedback = $this->getActiveFeedback()): ?>
3
- <?php $feedbackIds = array(0,1); ?>
4
- <?php foreach ($feedbackIds as $feedbackId): ?>
5
- <p class="factfinder-feedbackCampaign"><?php echo $feedback->getFeedback($feedbackId) ?></p>
6
- <?php endforeach; ?>
7
- <?php endif; ?>
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/campaigns/advisory.phtml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+ ?>
13
+ <?php $questions = $this->getActiveQuestions() ?>
14
+ <?php if (!empty($questions)): ?>
15
+ <?php foreach ($questions as $question): ?>
16
+ <div class="factfinder-advisorCampaign">
17
+ <p class="factfinder-advisorCampaign-question"><?php echo $question->getText() ?></p>
18
+ <ul>
19
+ <?php foreach ($question->getAnswers() as $answer): ?>
20
+ <?php //foreach ($answer->getFollowUpQuestions() as $question): ?>
21
+ <?php //$question->getAnswers(); ?>
22
+ <?php //endforeach; ?>
23
+ <li>
24
+ <a class="factfinder-advisorCampaign-answer" href="<?php echo $answer->getUrl() ?>">
25
+ <?php echo $answer->getText() ?>
26
+ </a>
27
+ </li>
28
+ <?php endforeach; ?>
29
+ </ul>
30
+ </div>
31
+ <?php endforeach; ?>
32
+ <?php endif; ?>
app/design/frontend/base/default/template/factfinder/campaigns/feedback.phtml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+ ?>
13
+ <p class="factfinder-feedbackCampaign">
14
+ <?php echo $this->getActiveFeedback(); ?>
15
+ </p>
app/design/frontend/base/default/template/factfinder/campaigns/pushed.phtml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Campaigns
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Campaigns
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015, Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ */
12
+ ?>
13
+
14
+ <?php if(count($this->getItemCollection()->getItems())): ?>
15
+ <div class="upsell">
16
+ <p class="factfinder-feedbackCampaign"><?php echo $this->getChildHtml('feedback_above'); ?></p>
17
+ <h2><?php echo $this->getHeader() ?></h2>
18
+ <ul id="pushed-products-list" class="products-grid products-grid--max-<?php echo $this->getMaxColNum(); ?>-col">
19
+ <?php foreach ($this->getItemCollection()->getItems() as $_item): ?>
20
+ <li class="item">
21
+ <a class="product-image" href="<?php echo $_item->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>">
22
+ <img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(210); ?>" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" />
23
+ </a>
24
+ <div class="product-details">
25
+ <h3 class="product-name"><a href="<?php echo $_item->getProductUrl() ?>"><?php echo $this->escapeHtml($_item->getName()) ?></a></h3>
26
+ <?php echo $this->getPriceHtml($_item, true) ?>
27
+ <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_item) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
28
+ <ul class="add-to-links">
29
+ <?php if ($this->helper('wishlist')->isAllow()) : ?>
30
+ <li><a href="<?php echo $this->getAddToWishlistUrl($_item) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
31
+ <?php endif; ?>
32
+ <?php if($_compareUrl=$this->getAddToCompareUrl($_item)): ?>
33
+ <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
34
+ <?php endif; ?>
35
+ </ul>
36
+ </div>
37
+ </li>
38
+ <?php endforeach; ?>
39
+ </ul>
40
+ <p class="factfinder-feedbackCampaign"><?php echo $this->getChildHtml('feedback_below'); ?></p>
41
+ </div>
42
+ <?php endif; ?>
43
+
app/design/frontend/base/default/template/factfinder/core/export/locked.phtml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+ ?>
14
+ <?php
15
+ echo $this->__('Another export is already running. Please wait for it to finish before you start a new export.');
16
+ ?>
17
+ <br />
18
+ <?php
19
+ echo $this->__('If you receive this message after another export has failed, please delete the file "ffexport.lock" within your Magento directory.');
app/design/frontend/base/default/template/factfinder/core/export/nofile.phtml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Core
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Core
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+ ?>
14
+ <?php
15
+ echo $this->__('Currently there is no pre-generated file for your resource request.');
16
+ ?>
17
+ <br />
18
+ <?php
19
+ echo $this->__('Please start an export request in the backend or wait until the file is generated through the cron.');
app/design/frontend/base/default/template/factfinder/filter/scriptaculousSlider.phtml DELETED
@@ -1,103 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Slider HTML Template
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @version $Id$
18
- */
19
- ?>
20
-
21
- <style type="text/css"><!--
22
- input.slider-label {
23
- background-color: #F1F1F1;
24
- border: 1px solid #ACACAC;
25
- font-size: 9px;
26
- height: 20px;
27
- margin: 10px 0 0;
28
- text-align: center;
29
- width: 40px;
30
- }
31
-
32
- input.slider-range-min {
33
- float: left;
34
- }
35
-
36
- input.slider-range-max {
37
- float: right;
38
- }
39
-
40
- div.slider {
41
- margin: 10px 0;
42
- background-color: #555;
43
- height:10px;
44
- position: relative;
45
- }
46
-
47
- span.slider-span {
48
- position: absolute;
49
- background-color: #6683B4;
50
- height: 10px;
51
- }
52
-
53
- div.slider div.handle {
54
- width: 10px;
55
- height: 18px;
56
- background-color: #F6F6F6;
57
- border: 1px solid #7F7F7F;
58
- cursor:move;
59
- position: absolute;
60
- margin-top: -5px;
61
- }
62
- --></style>
63
-
64
- <ol>
65
- <?php foreach ($this->getItems() as $_item): ?>
66
- <li>
67
- <input type="text" readonly="readonly" class="slider-label slider-range-min" value="<?php echo $this->getSelectedMin(), ' ', $this->getUnit(); ?>" />
68
- <input type="text" readonly="readonly" class="slider-label slider-range-max" value="<?php echo $this->getSelectedMax(), ' ', $this->getUnit(); ?>" />
69
- <div style="clear: both;"></div>
70
- <div id="<?php echo base64_encode($this->getValue());?>_slider" class="slider" style="width: 170px;">
71
- <span id="<?php echo base64_encode($this->getValue());?>_span" class="slider-span"></span>
72
- <div class="handle"></div>
73
- <div class="handle"></div>
74
- </div>
75
- <script type="text/javascript" language="javascript">
76
- //<![CDATA[
77
-
78
- (function() {
79
- var slider = $('<?php echo base64_encode($this->getValue());?>_slider');
80
- var minLabel = slider.siblings().grep(new Selector('.slider-range-min'))[0];
81
- var maxLabel = slider.siblings().grep(new Selector('.slider-range-max'))[0];
82
-
83
- new Control.Slider(slider.select('.handle'), slider, {
84
- range: $R(<?php echo $this->getAbsoluteMin();?>, <?php echo $this->getAbsoluteMax();?>),
85
- values: $R(<?php echo $this->getAbsoluteMin();?>, <?php echo $this->getAbsoluteMax();?>),
86
- sliderValue: [<?php echo $this->getSelectedMin();?>, <?php echo $this->getSelectedMax();?>],
87
- restricted: true,
88
- spans: ["<?php echo base64_encode($this->getValue());?>_span"],
89
- onSlide: function(values) {
90
- minLabel.setValue(values[0] + " <?php echo $this->getUnit();?>");
91
- maxLabel.setValue(values[1] + " <?php echo $this->getUnit();?>");
92
- },
93
- onChange: function(values) {
94
- var url = decodeURI('<?php echo $_item->getUrl() ?>');
95
- window.location.href= url.replace('[VALUE]',values[0] + '+-+' + values[1]);
96
- }
97
- });
98
- })();
99
- //]]>
100
- </script>
101
- </li>
102
- <?php endforeach ?>
103
- </ol>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/filter/slider.phtml DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Slider HTML Template
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @version $Id$
18
- */
19
- ?>
20
- <ol>
21
- <?php foreach ($this->getItems() as $_item): ?>
22
- <li>
23
- <div id="<?php echo base64_encode($this->getValue());?>" style="width: 170px;padding:10px 0px;"></div>
24
- <script type="text/javascript" language="javascript">
25
- //<![CDATA[
26
-
27
- Event.observe(document, 'ffslider:init', function(event){
28
- oneTouchSlider.addSlider({
29
- hostElementId:'<?php echo base64_encode($this->getValue());?>',
30
- leftBorder: <?php echo $this->getAbsoluteMin();?>,
31
- rightBorder: <?php echo $this->getAbsoluteMax();?>,
32
- currentLeft: <?php echo $this->getSelectedMin();?>,
33
- currentRight: <?php echo $this->getSelectedMax();?>,
34
- unit:"<?php echo $this->getUnit();?>",
35
- callback:function(left, right){
36
- var url = decodeURI('<?php echo $_item->getUrl() ?>');
37
- window.location.href= url.replace('[VALUE]',left + '+-+' + right);
38
- }
39
- });
40
- }
41
- );
42
- //]]>
43
- </script>
44
- </li>
45
- <?php endforeach ?>
46
- </ol>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/form.advancedsuggest.phtml DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Advanced Template to replace Javascript Suggest
12
- * NOTICE: This template will only work if suggests are requested from the proxy (see option in section "FACT-Finder Config Data" in Magento's backend)!
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- ?>
21
-
22
- <form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
23
- <div class="form-search">
24
- <label for="search"><?php echo $this->__('Search:') ?></label>
25
- <input id="search" type="text" name="<?php echo $this->helper('catalogsearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogsearch')->getEscapedQueryText() ?>" class="input-text ff-basic-autocomplete" />
26
- <button type="submit" title="<?php echo $this->__('Search') ?>" class="button"><span><span><?php echo $this->__('Search') ?></span></span></button>
27
- <div id="search_autocomplete" class="search-autocomplete advanced-suggest"></div>
28
- <script type="text/javascript">
29
- //<![CDATA[
30
- <?php if (Mage::helper('factfinder/search')->getIsEnabled(false, 'suggest')):?>
31
-
32
- var loadDataCallback = function(data) {
33
- // Internationalization lookup:
34
- // Add a new anonymous object for every string you want to internationalize (with the property being the string).
35
- // These objects consist of one string for each locale, where the property is the locale code.
36
- var i18n = {
37
- <?php
38
- $channels = array_filter(explode(';', Mage::getStoreConfig('factfinder/search/secondary_channels')));
39
- $output = array();
40
- foreach($channels as $channel)
41
- $output[] = '"Channel: '.$channel.'" : "'.$this->__('Channel: '.$channel).'"';
42
- echo implode(',', $output);
43
- ?>
44
- };
45
- var translate = function(string) {
46
- if(i18n[string] == undefined)
47
- return string;
48
- else
49
- return i18n[string];
50
- }
51
-
52
- var content = '<ul>';
53
- content += '<li style="display: none" class="selected selectable-item"></li>';
54
- var currentChannel = '';
55
- <?php if (Mage::helper('factfinder/search')->isSuggestProxyActivated()): ?>
56
- if(data.length) {
57
- if(data[0].channel == '<?php echo Mage::getStoreConfig('factfinder/search/channel'); ?>') {
58
- content += '<li class="delimiter"><?php echo $this->__('Products'); ?></li>';
59
- } else {
60
- content += '<li class="delimiter">' + translate('Channel: ' + data[0].channel) + '</li>';
61
- }
62
- currentChannel = data[0].channel;
63
- }
64
- <?php endif; ?>
65
-
66
- for(var i = 0; i < data.length; i++) {
67
- var item = data[i];
68
- if(item.channel != undefined && item.channel != currentChannel)
69
- {
70
- content += '<li class="delimiter">' + translate('Channel: ' + item.channel) + '</li>';
71
- currentChannel = item.channel;
72
- }
73
- var temp = '';
74
- temp += '<li title="' + (item.query ? item.query : item.name) + '" class="selectable-item ' + item.type + '">';
75
- temp += '<span class="amount">' + (item.hitCount == 0 ? '' : item.hitCount) + '</span>';
76
- if(item.imageURL)
77
- {
78
- temp += '<img src="' + item.imageURL + '" title="' + (item.query ? item.query : item.name) + '" class="thumbnail"/>';
79
- }
80
- temp += item.query ? item.query : item.name;
81
- temp += '</li>';
82
- content += temp;
83
- }
84
- content += '</ul>';
85
- return content;
86
- };
87
-
88
- var searchForm = new FactFinderSuggest('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>', loadDataCallback);
89
- searchForm.initAutocomplete('<?php echo $this->helper('factfinder/search')->getSuggestUrl() ?>', 'search_autocomplete');
90
- <?php else:?>
91
- var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>');
92
- searchForm.initAutocomplete('<?php echo $this->helper('catalogsearch')->getSuggestUrl() ?>', 'search_autocomplete');
93
- <?php endif;?>
94
- //]]>
95
- </script>
96
- </div>
97
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/form.advancedsuggest68.phtml DELETED
@@ -1,111 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Advanced Template to replace Javascript Suggest
12
- * NOTICE: This template will only work if suggests are requested from the proxy (see option in section "FACT-Finder Config Data" in Magento's backend)!
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- ?>
21
-
22
- <form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
23
- <div class="form-search">
24
- <label for="search"><?php echo $this->__('Search:') ?></label>
25
- <input id="search" type="text" name="<?php echo $this->helper('catalogsearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogsearch')->getEscapedQueryText() ?>" class="input-text ff-basic-autocomplete" />
26
- <button type="submit" title="<?php echo $this->__('Search') ?>" class="button"><span><span><?php echo $this->__('Search') ?></span></span></button>
27
- <div id="search_autocomplete" class="search-autocomplete advanced-suggest"></div>
28
- <script type="text/javascript">
29
- //<![CDATA[
30
- <?php if (Mage::helper('factfinder/search')->getIsEnabled(false, 'suggest')):?>
31
-
32
- var loadDataCallback = function(data) {
33
- // Internationalization lookup:
34
- // Add a new anonymous object for every string you want to internationalize (with the property being the string).
35
- // These objects consist of one string for each locale, where the property is the locale code.
36
- var i18n = {
37
- <?php
38
- $channels = array_filter(explode(';', Mage::getStoreConfig('factfinder/search/secondary_channels')));
39
- $output = array();
40
- foreach($channels as $channel)
41
- $output[] = '"Channel: '.$channel.'" : "'.$this->__('Channel: '.$channel).'"';
42
- echo implode(',', $output);
43
- ?>
44
- };
45
- var translate = function(string) {
46
- if(i18n[string] == undefined)
47
- return string;
48
- else
49
- return i18n[string];
50
- }
51
-
52
- // Try to get channel from search request, if no channel was found
53
- for(var i = 0; i < data.length; i++) {
54
- if(typeof(data[i].channel) == 'undefined' || data[i].channel == '') {
55
- var params = data[i].searchParams.toQueryParams();
56
- if(typeof(params.channel) != 'undefined') {
57
- data[i].channel = params.channel;
58
- }
59
- }
60
- }
61
-
62
- var content = '<ul>';
63
- content += '<li style="display: none" class="selected selectable-item"></li>';
64
- var currentChannel = '';
65
- if(data.length) {
66
- if(data[0].channel == '<?php echo Mage::getStoreConfig('factfinder/search/channel'); ?>') {
67
- content += '<li class="delimiter"><?php echo $this->__('Products'); ?></li>';
68
- } else if (typeof(data[i].channel) !== 'undefined') {
69
- content += '<li class="delimiter">' + translate('Channel: ' + data[0].channel) + '</li>';
70
- }
71
- currentChannel = data[0].channel;
72
- }
73
-
74
- for(var i = 0; i < data.length; i++) {
75
- var item = data[i];
76
- if(typeof(item.channel) !== 'undefined' && item.channel != currentChannel)
77
- {
78
- content += '<li class="delimiter">' + translate('Channel: ' + item.channel) + '</li>';
79
- currentChannel = item.channel;
80
- }
81
- var temp = '';
82
- temp += '<li title="' + item.name + '" class="selectable-item ' + item.type + '"';
83
- if(item.attributes.deeplink != undefined && item.attributes.deeplink != '')
84
- {
85
- temp += ' rel="' + item.attributes.deeplink + '"';
86
- }
87
- temp += '>';
88
-
89
- temp += '<span class="amount">' + (item.hitCount == 0 ? '' : item.hitCount) + '</span>';
90
- if(item.image)
91
- {
92
- temp += '<img src="' + item.image + '" title="' + item.name + '" class="thumbnail"/>';
93
- }
94
- temp += item.name;
95
- temp += '</li>';
96
- content += temp;
97
- }
98
- content += '</ul>';
99
- return content;
100
- };
101
-
102
- var searchForm = new FactFinderSuggest('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>', loadDataCallback);
103
- searchForm.initAutocomplete('<?php echo $this->helper('factfinder/search')->getSuggestUrl() ?>', 'search_autocomplete');
104
- <?php else:?>
105
- var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>');
106
- searchForm.initAutocomplete('<?php echo $this->helper('catalogsearch')->getSuggestUrl() ?>', 'search_autocomplete');
107
- <?php endif;?>
108
- //]]>
109
- </script>
110
- </div>
111
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/form.mini.phtml DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Template to replace Javascript Suggest
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @version $Id$
18
- */
19
- ?>
20
- <form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
21
- <div class="form-search">
22
- <label for="search"><?php echo $this->__('Search:') ?></label>
23
- <input id="search" type="text" name="<?php echo $this->helper('catalogsearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogsearch')->getEscapedQueryText() ?>" class="input-text ff-basic-autocomplete" />
24
- <button type="submit" title="<?php echo $this->__('Search') ?>" class="button"><span><span><?php echo $this->__('Search') ?></span></span></button>
25
- <div id="search_autocomplete" class="search-autocomplete"></div>
26
- <script type="text/javascript">
27
- //<![CDATA[
28
- <?php if (Mage::helper('factfinder/search')->getIsEnabled(false, 'suggest')):?>
29
-
30
- var loadDataCallback = function(data) {
31
- var content = '<ul>';
32
- content += '<li style="display: none;" class="selected selectable-item"></li>';
33
- data.each(function(item) {
34
- var temp = '';
35
- temp += '<li title="' + item.query + '" class="selectable-item">';
36
- temp += '<span class="amount">' + (item.hitCount == 0 ? '' : item.hitCount) + '</span>';
37
- temp += item.query;
38
- temp += '</li>';
39
- content += temp;
40
- });
41
- content += '</ul>';
42
- return content;
43
- };
44
-
45
- var searchForm = new FactFinderSuggest('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>', loadDataCallback);
46
- searchForm.initAutocomplete('<?php echo $this->helper('factfinder/search')->getSuggestUrl() ?>', 'search_autocomplete');
47
- <?php else:?>
48
- var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('Search entire shop here...') ?>');
49
- searchForm.initAutocomplete('<?php echo $this->helper('catalogsearch')->getSuggestUrl() ?>', 'search_autocomplete');
50
- <?php endif;?>
51
- //]]>
52
- </script>
53
- </div>
54
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/logo.phtml DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Add FACT-Finder Logo to Search Result
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @version $Id$
18
- */
19
- ?>
20
- <?php if(Mage::helper('factfinder/search')->getIsEnabled()):?>
21
- <div style="text-align:center;margin: 10px auto;"><a href="http://www.fact-finder.de"><img src="http://www.fact-finder.de/files/fact_finder_conversion.jpg" border="0" alt="on-site search & navigation – conversion engine FACT-Finder" target="_blank" width="116" height="35"></a></div>
22
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/secondaryresult.phtml DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Add a list of secondary results to Search Result
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @version $Id$
18
- */
19
- ?>
20
- <?php
21
-
22
- // array_filter() is used to turn a one-element array into an empty array in the case of an empty config-string
23
- $channels = array_filter(explode(';', Mage::getStoreConfig('factfinder/search/secondary_channels')));
24
-
25
- if(Mage::helper('factfinder/search')->getIsEnabled() && !empty($channels)):
26
-
27
- ?>
28
-
29
- <div>
30
- <?php echo $this->__('Secondary Result'); ?>:
31
- <br><br>
32
- <?php
33
- $result = $this->getSecondaryResult($channels[0]);
34
- foreach($result AS $record)
35
- {
36
- echo $record->getValue("Title")."<br/>";
37
- }
38
- ?>
39
- </div>
40
-
41
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/suggest/advancedsuggest.phtml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Suggest
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Suggest
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+ /*
14
+ * Advanced Template to replace Javascript Suggest
15
+ * NOTICE: This template will only work if suggests are requested from the proxy
16
+ * (see option in section "FACT-Finder Config Data" in Magento's backend)!
17
+ */
18
+ ?>
19
+ <?php $catalogSearchHelper = $this->helper('catalogsearch'); ?>
20
+ <form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
21
+ <div class="form-search">
22
+ <div class="input-box">
23
+ <label for="search"><?php echo $this->__('Search:') ?></label>
24
+ <input id="search" type="search" name="<?php echo $catalogSearchHelper->getQueryParamName() ?>"
25
+ value="<?php echo $catalogSearchHelper->getEscapedQueryText() ?>" class="input-text required-entry"
26
+ maxlength="<?php echo $catalogSearchHelper->getMaxQueryLength();?>"
27
+ placeholder="<?php echo $this->__('Search entire store here...') ?>" />
28
+ <button type="submit" title="<?php echo $this->__('Search') ?>" class="button search-button">
29
+ <span><span><?php echo $this->__('Search') ?></span></span>
30
+ </button>
31
+ </div>
32
+ <div id="search_autocomplete" class="search-autocomplete advanced-suggest"></div>
33
+ </div>
34
+ </form>
35
+ <script type="text/javascript">
36
+ //<![CDATA[
37
+ var searchForm;
38
+ <?php if (Mage::helper('factfinder')->isEnabled('suggest')): ?>
39
+ searchForm = new FactFinderSuggest(
40
+ 'search_mini_form', 'search',
41
+ '<?php echo $this->__('Search entire store here...') ?>',
42
+ <?php echo $this->getTranslationsAsJson(); ?>,
43
+ '<?php echo Mage::getStoreConfig('factfinder/search/channel'); ?>'
44
+ );
45
+ <?php else: ?>
46
+ searchForm = new Varien.searchForm('search_mini_form', 'search',
47
+ '<?php echo $this->__('Search entire shop here...') ?>'
48
+ );
49
+ <?php endif; ?>
50
+
51
+ searchForm.initAutocomplete(
52
+ '<?php echo $this->helper('factfinder_suggest')->getSuggestUrl() ?>',
53
+ 'search_autocomplete'
54
+ );
55
+
56
+ //]]>
57
+ </script>
app/design/frontend/base/default/template/factfinder/tracking.phtml DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * Flagbit_FactFinder
4
- *
5
- * @category Mage
6
- * @package Flagbit_FactFinder
7
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
8
- */
9
-
10
- /**
11
- * Add FACT-Finder Tracking
12
- *
13
- * @category Mage
14
- * @package Flagbit_FactFinder
15
- * @copyright Copyright (c) 2013 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
16
- * @author Joerg Weller <weller@flagbit.de>
17
- * @author Nicolai Essig <nicolai.essig@flagbit.de>
18
- * @version $Id$
19
- */
20
- ?>
21
- <script type="text/javascript">
22
- var factfinderTracking = new FactfinderTracking(
23
- '.col-main',
24
- $H(<?php echo $this->getJsonDataObject();?>),
25
- $H(<?php echo $this->getJsonUrlToIdMappingObject();?>),
26
- '<?php echo $this->getUrl(Mage::helper('factfinder')->getTrackingUrlPath()) ?>',
27
- false
28
- );
29
-
30
- Event.observe(document, 'dom:loaded', function(event) {
31
- factfinderTracking.init();
32
- });
33
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/base/default/template/factfinder/tracking/init.phtml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FACTFinder_Tracking
4
+ *
5
+ * @category Mage
6
+ * @package FACTFinder_Tracking
7
+ * @author Flagbit Magento Team <magento@flagbit.de>
8
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ * @link http://www.flagbit.de
11
+ *
12
+ */
13
+ ?>
14
+ <script type="text/javascript">
15
+ var factfinderTracking = new FactfinderTracking(
16
+ '.col-main',
17
+ $H(<?php echo $this->getJsonDataObject();?>),
18
+ $H(<?php echo $this->getJsonUrlToIdMappingObject();?>),
19
+ '<?php echo $this->getUrl(Mage::helper('factfinder_tracking')->getTrackingUrlPath()) ?>',
20
+ false
21
+ );
22
+
23
+ Event.observe(document, 'dom:loaded', function(event) {
24
+ factfinderTracking.init();
25
+ });
26
+ </script>
app/etc/factfinder.xml CHANGED
@@ -1,28 +1,10 @@
1
  <?xml version='1.0' encoding="utf-8" ?>
2
- <!--
3
- /**
4
- * Flagbit_FactFinder
5
- *
6
- * @category Mage
7
- * @package Flagbit_FactFinder
8
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
9
- */
10
-
11
- /**
12
- * Module Config
13
- *
14
- * @category Mage
15
- * @package Flagbit_FactFinder
16
- * @copyright Copyright (c) 2010 Flagbit GmbH & Co. KG (http://www.flagbit.de/)
17
- * @author Joerg Weller <weller@flagbit.de>
18
- * @version $Id$
19
- */
20
- -->
21
  <config>
22
  <global>
23
  <cache>
24
  <request_processors>
25
- <factfinder>Flagbit_FactFinder_Model_Processor</factfinder>
 
26
  </request_processors>
27
  </cache>
28
  </global>
1
  <?xml version='1.0' encoding="utf-8" ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <config>
3
  <global>
4
  <cache>
5
  <request_processors>
6
+ <ff_suggest>FACTFinder_Suggest_Model_Processor</ff_suggest>
7
+ <ff_tracking>FACTFinder_Tracking_Model_Processor</ff_tracking>
8
  </request_processors>
9
  </cache>
10
  </global>
app/etc/modules/Flagbit_FactFinder.xml DELETED
@@ -1,9 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Flagbit_FactFinder>
5
- <active>true</active>
6
- <codePool>community</codePool>
7
- </Flagbit_FactFinder>
8
- </modules>
9
- </config>
 
 
 
 
 
 
 
 
 
app/locale/de_DE/Flagbit_FactFinder.csv DELETED
@@ -1,91 +0,0 @@
1
- "advanced", "fortgeschritten"
2
- "Advanced Authentication Postfix", "Suffix für fortgeschrittene Authentifizierung"
3
- "Advanced Authentication Prefix", "Präfix für fortgeschrittene Authentifizierung"
4
- "After three failed attempts, the module can revert to using Magento for searches. After the specified amount of time has passed, the module will try to contact FACT-Finder again. If you enter 0, the module will first attempt to contact FACT-Finder for every search.", "Nach drei fehlgeschlagenen Versuchen, kann das Modul dauerhaft Magentos Suche benutzen. Nachdem die hier eingegebene Zeit verstrichen ist, versucht das Modul dann erneut FACT-Finder zu verwenden. Wenn Sie 0 eingeben, wird das Modul für alle Suchanfragen zunächst versuchen FACT-Finder zu erreichen."
5
- "Another export is already running. Please wait for it to finish before you start a new export.", "Ein anderer Export wurde bereits gestartet. Bitte warten Sie auf dessen Fertigstellung, bevor Sie ein neuen Export beginnen."
6
- "If you receive this message after another export has failed, please delete the file ""export.lock"" within your Magento directory.", "Wenn Sie diese Meldung sehen, nachdem ein anderer Export abgebrochen wurde, löschen Sie bitte die Datei ""export.lock"" aus Ihrem Magento-Verzeichnis."
7
- "Authentication Type", "Authentifizierungstyp"
8
- "Catalog", "Katalog"
9
- "Channel", "Channel"
10
- "Channel does not exist or the specified user does not have sufficient rights.", "Channel existiert nicht oder der verwendete User hat nicht die benötigten Rechte."
11
- "Channel: dev-content", "Inhalte"
12
- "Please select the version of your FACT-Finder application to enable all of its features.", "Wählen Sie die Version Ihrer FACT-Finder-Applikation um alle Funktionen nutzen zu können."
13
- "Context Name", "Kontext-Name"
14
- "Could not establish HTTP connection.", "HTTP-Verbindung konnte nicht hergestellt werden."
15
- "Could not log into FACT-Finder with the given settings. Please check username, password, prefix and postfix.", "FACT-Finder-Login mit gegebenen Einstellungen nicht möglich. Bitte überprüfen Sie Benutzernamen, Passwort, Präfix und Suffix."
16
- "Could not contact FACT-Finder.", "FACT-Finder konnte nicht erreicht werden."
17
- "Debug Log", "Debug Log"
18
- "Download export", "Export herunterladen"
19
- "Enabled", "Aktiviert"
20
- "Enter your internal IP addresses. Multiple IP addresses should be separated by semicolons.", "Geben Sie hier Ihre internen IP-Adressen ein. Mehrere IP-Adressen werden mit Semikolon getrennt."
21
- "Enter any secondary channels you want to search. Multiple channels should be separated by semicolons. NOTE: Secondary channels will only be considered for Suggest results if the proxy is used (see option in section ""FACT-Finder Config Data"")!", "Geben Sie hier weitere Channels an, die Sie durchsuchen wollen. Mehrere Channels werden mit Semikolon getrennt. Hinweis: Damit sekundäre Channels in der Autovervollständigung berücksichtigt werden, muss der Proxy verwendet werden (siehe Option im Abschnitt ""FACT-Finder Konfigurationsdaten"")!"
22
- "Error in Channel", "Fehler in Channel"
23
- "Error in Primary Channel", "Fehler im primären Channel"
24
- "Export Images and Deeplinks", "Bilder und Deeplinks exportieren"
25
- "FACT-Finder", "FACT-Finder"
26
- "FACT-Finder Access Data", "FACT-Finder: Zugangsdaten"
27
- "FACT-Finder Business User Cockpit", "FACT-Finder Business User Cockpit"
28
- "FACT-Finder can provide multiple search indexes, each represented by a ""channel"". Enter the channel that will be filled with your Magento export. Leave empty to use the default channel.", "FACT-Finder kann mehrere Such-Indizes zur Verfügung stellen. Jeder Index wird durch einen ""Channel"" dargestellt. Tragen Sie den Channel ein, der mit Ihrem Magento-Export gefüllt wird. Wenn kein Wert angegeben ist, wird der Standard-Channel genutzt."
29
- "FACT-Finder cannot be activated:", "FACT-Finder konnte nicht aktiviert werden:"
30
- "FACT-Finder Config Data", "FACT-Finder-Konfigurationsdaten"
31
- "FACT-Finder Export Configuration", "FACT-Finder: Export-Konfiguration"
32
- "FACT-Finder Fallback Configuration", "FACT-Finder: Fallback-Konfiguration"
33
- "FACT-Finder Module Activation", "FACT-Finder: Modul-Auswahl"
34
- "FACT-Finder not found on server. Please check your context setting.", "FACT-Finder konnte auf dem Server nicht gefunden werden. Bitte überprüfen Sie Ihre Kontexteinstellung."
35
- "FACT-Finder Status", "FACT-Finder Status"
36
- "FACT-Finder version", "FACT-Finder-Version"
37
- "http", "http"
38
- "If activated and FACT-Finder cannot be contacted, Magento's built-in search will be used instead.", "Wenn diese Option aktiviert ist und FACT-Finder nicht erreicht werden kann, wird stattdessen Magentos eingebaute Suche verwendet."
39
- "Internal IPs", "Interne IPs"
40
- "Language", "Sprache"
41
- "Minutes before next attempt", "Minuten bis zum erneuten Versuch"
42
- "Name of the FACT-Finder application", "Name der FACT-Finder-Applikation"
43
- "No", "Nein"
44
- "Password", "Passwort"
45
- "Please enter the desired edge length of the Suggest images in pixels. If you do not want them to be resized, enter 0.", "Bitte tragen Sie die gewünschte Seitenlänge der Autovervollständigungs-Bilder in Pixeln ein. Wenn die Bilder in Originalgröße abgelegt werden sollen, tragen Sie 0 ein."
46
- "Primary Channel", "Primärer Channel"
47
- "Product ID (default)", "Produkt-ID (Standard)"
48
- "Product Identifier", "Produkt-Identifizierung"
49
- "Product SKU", "Produkt-SKU (Artikelnummer)"
50
- "Products", "Produkte"
51
- "Redirect to product details page for single results", "Bei eindeutigem Resultat auf Produkt-Detailseite weiterleiten"
52
- "Secondary Result", "Sekundäre Ergebnisse"
53
- "Search", "Suche"
54
- "Search entire shop here...", "Den gesamten Shop durchsuchen..."
55
- "Search:", "Suche:"
56
- "Secondary Channels", "Sekundäre Channel"
57
- "Server Port", "Server-Port"
58
- "Server URL", "Server-URL"
59
- "The server name should contain only the IP address or the domain - no ""http://"" or any slashes!", "Der Servername sollte ausschließlich die IP-Adresse oder die Domain enthalten - kein ""http://"" und keine Slashes (/ oder \)!"
60
- "simple", "einfach"
61
- "Size of Suggest images", "Größe der Autovervollständigungs-Bilder"
62
- "Type of Suggest images", "Typ der Autovervollständigungs-Bilder"
63
- "Some text strings come directly from FACT-Finder. Enter the language code here. Leave empty to use the language specified by the user's browser.", "Einige Texte kommen direkt von FACT-Finder. Mit dem Sprach-Code in diesem Feld können Sie die Sprache festlegen. Bei leerem Wert erhält der Benutzer Labels in seiner angegebenen Browser-Sprache."
64
- "The advanced authentication post- and prefix are only used when the authentication type is ""advanced"".", "Die Werte der Prä- und Suffixes werden ausschließlich bei fortgeschrittener Authentifizierung verwendet."
65
- "The configuration has been saved.", "Die Konfigurationsdaten wurden gespeichert."
66
- "The configured FACT-Finder version is higher than the actual version of your FACT-Finder. Consider upgrading your FACT-Finder, or reduce the configured version to ", "Die eingestellte FACT-Finder-Version ist höher als die tatsächliche Version Ihres FACT-Finders. Überlegen Sie Ihren FACT-Finder zu erneuern, oder reduzieren Sie die eingestellte Version auf "
67
- "The value for ""port"" must be an integer!", "Der Wert für den Server-Port muss numerisch sein!"
68
- "The value for ""port"" must be an integer greater or equals 80!", "Der Wert für den Server-Port muss größer oder gleich 80 sein!"
69
- "An unknown error has occurred. Please contact FACT-Finder Support.", "Unbekannter Fehler aufgetreten. Bitte kontaktieren Sie Ihren FACT-Finder-Support."
70
- "There is a Class Rewrite Conflict: ""%s"" already overwritten by ""%s""", "Es besteht ein Klassen-Rewrite-Konflikt: ""%s"" wurde bereits durch ""%s"" überschrieben!"
71
- "There is a problem with FACT-Finder. Please contact FACT-Finder Support.", "Es besteht ein Problem mit FACT-Finder. Bitte kontaktieren Sie Ihren FACT-Finder-Support."
72
- "A user name must be provided if a password is to be used.", "Sie müssen einen Benutzernamen verwenden."
73
- "This option must be enabled if secondary channels are to be considered for Suggest results.", "Diese Option muss aktiviert sein, damit sekundäre Channels in der Autovervollständigung berücksichtigt werden."
74
- "Track ""Add to cart"" events", "Warenkorb-Events tracken"
75
- "Track checkout", "Verkaufte Produkte tracken"
76
- "Track product-clicks", "Produkt-Klicks tracken"
77
- "Use FACT-Finder After Search Navigation Functionality", "FACT-Finders After Search Navigation einsetzen"
78
- "Use FACT-Finder Campaign Functionality", "FACT-Finder-Kampagnen einsetzen"
79
- "Use FACT-Finder for Layered Navigation", "FACT-Finder für Layered Navigation einsetzen"
80
- "Use FACT-Finder for product cross-selling", "FACT-Finder für Cross-Sells einsetzen"
81
- "Use FACT-Finder for product upselling", "FACT-Finder für Upsells einsetzen"
82
- "Use FACT-Finder for tag cloud computation", "FACT-Finder für die Berechnung der TagCloud verwenden"
83
- "Use FACT-Finder Search", "FACT-Finder-Suche nutzen"
84
- "Use FACT-Finder Suggest Functionality", "FACT-Finder für Autovervollständigung verwenden"
85
- "Use Fallback", "Fallback verwenden"
86
- "Use Proxy for Suggest", "Proxy für Autovervollständigung nutzen"
87
- "User name", "Benutzername"
88
- "User name for authentication", "Benutzername für Authentifizierung"
89
- "Yes", "Ja"
90
- "Your server's clock does not agree with FACT-Finder's. Please make sure your clock is set correctly.", "Ihre Serverzeit stimmt nicht mit der von FACT-Finder überein. Bitte stellen Sie sicher, dass Ihre Serverzeit korrekt eingestellt ist."
91
- "Search Request Cache","Suchanfragen Cache"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/factfinder/jXHR.js CHANGED
@@ -6,16 +6,16 @@
6
  var SETTIMEOUT = global.setTimeout, // for better compression
7
  doc = global.document,
8
  callback_counter = 0;
9
-
10
  global.jXHR = function() {
11
  var script_url,
12
  script_loaded,
13
  jsonp_callback,
14
  scriptElem,
15
  publicAPI = null;
16
-
17
  function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }
18
-
19
  function reset() {
20
  script_loaded = false;
21
  script_url = "";
@@ -23,7 +23,7 @@
23
  scriptElem = null;
24
  fireReadyStateChange(0);
25
  }
26
-
27
  function ThrowError(msg) {
28
  try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }
29
  }
@@ -35,13 +35,13 @@
35
  if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");
36
  removeScript();
37
  }
38
-
39
  function fireReadyStateChange(rs,args) {
40
  args = args || [];
41
  publicAPI.readyState = rs;
42
  if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);
43
  }
44
-
45
  publicAPI = {
46
  onerror:null,
47
  onreadystatechange:null,
@@ -51,10 +51,10 @@
51
  internal_callback = "cb"+(callback_counter++);
52
  (function(icb){
53
  global.jXHR[icb] = function() {
54
- try { fireReadyStateChange.call(publicAPI,4,arguments); }
55
- catch(err) {
56
  publicAPI.readyState = -1;
57
- ThrowError("Script failed to run ["+script_url+"].");
58
  }
59
  global.jXHR[icb] = null;
60
  };
@@ -78,7 +78,7 @@
78
  };
79
 
80
  reset();
81
-
82
  return publicAPI;
83
  };
84
  })(window);
6
  var SETTIMEOUT = global.setTimeout, // for better compression
7
  doc = global.document,
8
  callback_counter = 0;
9
+
10
  global.jXHR = function() {
11
  var script_url,
12
  script_loaded,
13
  jsonp_callback,
14
  scriptElem,
15
  publicAPI = null;
16
+
17
  function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }
18
+
19
  function reset() {
20
  script_loaded = false;
21
  script_url = "";
23
  scriptElem = null;
24
  fireReadyStateChange(0);
25
  }
26
+
27
  function ThrowError(msg) {
28
  try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }
29
  }
35
  if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");
36
  removeScript();
37
  }
38
+
39
  function fireReadyStateChange(rs,args) {
40
  args = args || [];
41
  publicAPI.readyState = rs;
42
  if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);
43
  }
44
+
45
  publicAPI = {
46
  onerror:null,
47
  onreadystatechange:null,
51
  internal_callback = "cb"+(callback_counter++);
52
  (function(icb){
53
  global.jXHR[icb] = function() {
54
+ try { fireReadyStateChange.call(publicAPI,4,arguments); }
55
+ catch(err) {
56
  publicAPI.readyState = -1;
57
+ ThrowError("Script failed to run ["+script_url+"].");
58
  }
59
  global.jXHR[icb] = null;
60
  };
78
  };
79
 
80
  reset();
81
+
82
  return publicAPI;
83
  };
84
  })(window);
js/factfinder/suggest.js CHANGED
@@ -1,3 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
  var FactFinderAjax = {
2
  getTransport: function() {
3
  return new jXHR();
@@ -164,16 +176,15 @@ var FactFinderAutocompleter = Class.create(Ajax.Autocompleter, {
164
  getEntry: function(index) {
165
  return this.update.select('.selectable-item')[index];
166
  }
167
- })
168
 
169
  var FactFinderSuggest = Class.create(Varien.searchForm, {
170
- initialize : function($super, form, field, emptyText, loadDataCallback) {
171
  $super(form, field, emptyText);
172
- this.loadDataCallback = loadDataCallback;
 
173
  },
174
 
175
- loadDataCallback: null,
176
-
177
  request: null,
178
 
179
  initAutocomplete : function(url, destinationElement){
@@ -206,10 +217,22 @@ var FactFinderSuggest = Class.create(Varien.searchForm, {
206
 
207
  _loadData: function(data) {
208
  this.request.updateChoices(this.loadDataCallback(data));
 
 
 
 
 
 
 
 
 
 
209
  },
210
 
211
  _selectAutocompleteItem : function(element){
212
- if(element.attributes.rel) {
 
 
213
  document.location.href = element.attributes.rel.nodeValue;
214
  } else if(element.title) {
215
  this.form.insert('<input type="hidden" name="queryFromSuggest" value="true" />');
@@ -218,6 +241,104 @@ var FactFinderSuggest = Class.create(Varien.searchForm, {
218
  this.field.value = element.title;
219
 
220
  this.form.submit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
 
 
 
 
 
 
 
222
  }
223
  });
1
+ /**
2
+ * FACTFinder_Suggest
3
+ *
4
+ * @category Mage
5
+ * @package FACTFinder_Suggest
6
+ * @author Flagbit Magento Team <magento@flagbit.de>
7
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ * @link http://www.flagbit.de
10
+ *
11
+ */
12
+
13
  var FactFinderAjax = {
14
  getTransport: function() {
15
  return new jXHR();
176
  getEntry: function(index) {
177
  return this.update.select('.selectable-item')[index];
178
  }
179
+ });
180
 
181
  var FactFinderSuggest = Class.create(Varien.searchForm, {
182
+ initialize : function($super, form, field, emptyText, i18n, defaultChannel) {
183
  $super(form, field, emptyText);
184
+ this.i18n = i18n;
185
+ this.defaultChannel = defaultChannel;
186
  },
187
 
 
 
188
  request: null,
189
 
190
  initAutocomplete : function(url, destinationElement){
217
 
218
  _loadData: function(data) {
219
  this.request.updateChoices(this.loadDataCallback(data));
220
+ this.updateSelectionOnMouseMove();
221
+ },
222
+
223
+ updateSelectionOnMouseMove: function () {
224
+ $('suggest-options').observe('mouseleave', function (e) {
225
+ $$('#suggest-options .selected').each(function (option) {
226
+ option.removeClassName('selected');
227
+ this.field.focus();
228
+ }.bind(this));
229
+ }.bind(this));
230
  },
231
 
232
  _selectAutocompleteItem : function(element){
233
+ if (!element.hasClassName('selected')) {
234
+ this.form.submit();
235
+ } else if(element.attributes.rel) {
236
  document.location.href = element.attributes.rel.nodeValue;
237
  } else if(element.title) {
238
  this.form.insert('<input type="hidden" name="queryFromSuggest" value="true" />');
241
  this.field.value = element.title;
242
 
243
  this.form.submit();
244
+ } else {
245
+ this.form.submit();
246
+ }
247
+ },
248
+
249
+ loadDataCallback: function (data) {
250
+ if (data.suggestions) {
251
+ data = data.suggestions;
252
+ }
253
+
254
+ // Try to get channel from search request, if no channel was found
255
+ data.each(function (item) {
256
+ if (!item.channel) {
257
+ var params = item.searchParams.toQueryParams();
258
+ if (params.channel) {
259
+ item.channel = params.channel;
260
+ }
261
+ }
262
+ });
263
+
264
+
265
+ var content = '<ul id="suggest-options">';
266
+ content += '<li style="display: none" class="selected selectable-item"></li>';
267
+ var currentChannel = '';
268
+ var currentType = '';
269
+ if (data.length) {
270
+ if (data[0].channel != this.defaultChannel) {
271
+ content += '<li class="delimiter">' + this.translate('Channel: ' + data[0].channel) + '</li>';
272
+ }
273
+ currentChannel = data[0].channel;
274
+ }
275
+
276
+ data.each(function(item) {
277
+ if (item.channel != currentChannel) {
278
+ content += '<li class="delimiter">' + this.translate('Channel: ' + item.channel) + '</li>';
279
+ currentChannel = item.channel;
280
+ }
281
+
282
+ if (item.type != currentType) {
283
+ content += '<li class="delimiter">' + this.translate(item.type) + '</li>';
284
+ currentType = item.type;
285
+ }
286
+
287
+ var temp = '';
288
+ temp += '<li title="' + item.name + '" class="selectable-item ' + item.type + '"';
289
+ temp += ' rel="' + this.getItemUrl(item)+ '"';
290
+ temp += '>';
291
+
292
+ temp += '<span class="amount">' + (item.hitCount == 0 ? '' : item.hitCount) + '</span>';
293
+ if (item.image) {
294
+ temp += '<img src="' + item.image + '" title="' + item.name + '" class="thumbnail"/>';
295
+ }
296
+
297
+ temp += item.name.replace(new RegExp("("+this.field.value+")","ig"), '<strong>$1</strong>');
298
+
299
+ if (item.attributes.parentCategory) {
300
+ temp += ' (' + decodeURIComponent(item.attributes.parentCategory) + ')';
301
+ }
302
+
303
+ temp += '</li>';
304
+ content += temp;
305
+ }.bind(this));
306
+
307
+ content += '</ul>';
308
+
309
+ return content;
310
+ },
311
+
312
+ translate: function (string) {
313
+ // Internationalization lookup:
314
+ // Add a new anonymous object for every string you want to internationalize (with the property being the string).
315
+ // These objects consist of one string for each locale, where the property is the locale code.
316
+ if (this.i18n[string] === undefined) {
317
+ return string;
318
+ } else {
319
+ return this.i18n[string];
320
+ }
321
+ },
322
+
323
+ getItemUrl: function (item) {
324
+ if (item.attributes.deeplink) {
325
+ return item.attributes.deeplink;
326
+ }
327
+
328
+ var qPos = item.searchParams.indexOf('?');
329
+
330
+ var url = this.form.action;
331
+ if (url.indexOf('?') > 0) {
332
+ url += '&' + item.searchParams.substring(qPos + 1);
333
+ } else {
334
+ url += item.searchParams.substring(qPos);
335
  }
336
+
337
+ url += '&userInput='+this.field.value+'&queryFromSuggest=true';
338
+
339
+ //there's no mapping possibility, so let's hardcode it
340
+ url = url.replace('query=', 'q=');
341
+
342
+ return url;
343
  }
344
  });
js/factfinder/tracking.js CHANGED
@@ -1,62 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
  var FactfinderTracking = Class.create({
2
- url: null,
3
- data: null,
4
- classname: null,
5
- mapping: null,
6
- request: null,
7
- regex: new RegExp(/product\/([0-9]+)\//),
8
- asynchronous: true,
9
- initialize: function(classname, data, mapping, url, asynchronous) {
10
- this.classname = classname;
11
- this.data = data;
12
- this.mapping = mapping;
13
- this.url = url;
14
- if(typeof asynchronous !== 'undefined')
15
- this.asynchronous = asynchronous;
16
- },
17
-
18
- init: function() {
19
- $$(this.classname+' a',this.classname+' button').each(function(element) {
20
- this.mapping.each(function(pair, index) {
21
- if(element.readAttribute('href') && element.readAttribute('href').indexOf(pair.key) >= 0){
22
- return this.prepareElement(element, pair.value, 'click');
23
- }
24
- if(element.readAttribute('onclick') && element.readAttribute('onclick').indexOf(pair.key) >= 0){
25
- return this.prepareElement(element, pair.value, 'click');
26
- }
27
- }.bind(this));
28
-
29
- if(element.readAttribute('href')) {
30
- var match = this.regex.exec(element.readAttribute('href'));
31
- if(match && match[1]) {
32
- return this.prepareElement(element, match[1], 'click');
33
- }
34
- }
35
-
36
- if(element.readAttribute('onclick')) {
37
- var match = this.regex.exec(element.readAttribute('onclick'));
38
- if(match && match[1]) {
39
- return this.prepareElement(element, match[1], 'click');
40
- }
41
- }
42
- }.bind(this));
43
- },
44
-
45
- prepareElement: function(element, id, eventType) {
46
- Event.observe(element, 'click', function(event) {
47
- this.recordRequest(id, eventType);
48
- }.bind(this));
49
- },
50
-
51
- recordRequest: function(id, eventType) {
52
-
53
- var data = this.data.get(id);
54
-
55
- this.request = new Ajax.Request(this.url, {
56
- asynchronous: this.asynchronous,
57
- method: 'post',
58
- parameters: data
59
- });
60
- return false;
61
- }
62
- });
1
+ /**
2
+ * FACTFinder_Tracking
3
+ *
4
+ * @category Mage
5
+ * @package FACTFinder_Tracking
6
+ * @author Flagbit Magento Team <magento@flagbit.de>
7
+ * @copyright Copyright (c) 2015 Flagbit GmbH & Co. KG
8
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
+ * @link http://www.flagbit.de
10
+ *
11
+ */
12
+
13
  var FactfinderTracking = Class.create({
14
+ url: null,
15
+ data: null,
16
+ classname: null,
17
+ mapping: null,
18
+ request: null,
19
+ regex: new RegExp(/product\/([0-9]+)\//),
20
+ asynchronous: true,
21
+ initialize: function(classname, data, mapping, url, asynchronous) {
22
+ this.classname = classname;
23
+ this.data = data;
24
+ this.mapping = mapping;
25
+ this.url = url;
26
+ if(typeof asynchronous !== 'undefined')
27
+ this.asynchronous = asynchronous;
28
+ },
29
+
30
+ init: function() {
31
+ $$(this.classname+' a',this.classname+' button').each(function(element) {
32
+ this.mapping.each(function(pair, index) {
33
+ if(element.readAttribute('href') && element.readAttribute('href').indexOf(pair.key) >= 0){
34
+ return this.prepareElement(element, pair.value, 'click');
35
+ }
36
+ if(element.readAttribute('onclick') && element.readAttribute('onclick').indexOf(pair.key) >= 0){
37
+ return this.prepareElement(element, pair.value, 'click');
38
+ }
39
+ }.bind(this));
40
+
41
+ if(element.readAttribute('href')) {
42
+ var match = this.regex.exec(element.readAttribute('href'));
43
+ if(match && match[1]) {
44
+ return this.prepareElement(element, match[1], 'click');
45
+ }
46
+ }
47
+
48
+ if(element.readAttribute('onclick')) {
49
+ var match = this.regex.exec(element.readAttribute('onclick'));
50
+ if(match && match[1]) {
51
+ return this.prepareElement(element, match[1], 'click');
52
+ }
53
+ }
54
+ }.bind(this));
55
+ },
56
+
57
+ prepareElement: function(element, id, eventType) {
58
+ Event.observe(element, 'click', function(event) {
59
+ this.recordRequest(id, eventType);
60
+ }.bind(this));
61
+ },
62
+
63
+ recordRequest: function(id, eventType) {
64
+
65
+ var data = this.data.get(id);
66
+
67
+ this.request = new Ajax.Request(this.url, {
68
+ asynchronous: this.asynchronous,
69
+ method: 'post',
70
+ parameters: data
71
+ });
72
+ return false;
73
+ }
74
+ });
lib/FACTFinder/Abstract/Adapter.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Abstract
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * handles the issue to create useable object from the data delivered by the dataprovider.
12
- * this class can also be seen as a factory, but it is rather an adapter, because it converst the responded objects into
13
- * the useable, unique objects
14
- *
15
- * @author Rudolf Batt <rb@omikron.net>
16
- * @version $Id: Adapter.php 25893 2010-06-29 08:19:43Z rb $
17
- * @package FACTFinder\Abstract
18
- */
19
- abstract class FACTFinder_Abstract_Adapter
20
- {
21
- protected $paramsParser;
22
- protected $dataProvider;
23
- protected $encodingHandler;
24
-
25
- protected $log;
26
-
27
- protected $data;
28
-
29
- final public function __construct(FACTFinder_Abstract_DataProvider $dataProvider, FACTFinder_ParametersParser $paramsParser,
30
- FACTFinder_EncodingHandler $encodingHandler, FACTFinder_Abstract_Logger $log = null)
31
- {
32
- if(isset($log))
33
- $this->log = $log;
34
- else
35
- $this->log = FF::getSingleton('nullLogger');
36
- $this->setDataProvider($dataProvider);
37
- $this->setParamsParser($paramsParser);
38
- $this->setEncodingHandler($encodingHandler);
39
- $this->init();
40
- }
41
-
42
- /**
43
- * can be overwritten to do initialising issues, that would normaly done by the constructor. it will be called at
44
- * the end of the constructor
45
- *
46
- * @return void
47
- */
48
- protected function init(){}
49
-
50
- public function setParam($name, $value)
51
- {
52
- $this->getDataProvider()->setParam($name, $value);
53
- }
54
-
55
- public function setParams($params)
56
- {
57
- $this->getDataProvider()->setParams($params);
58
- }
59
-
60
- /**
61
- * decorates the dataprovider::getData method so a inheriting class does not have to use the dataprovider
62
- */
63
- protected function getData()
64
- {
65
- return $this->getDataProvider()->getData();
66
- }
67
-
68
- protected function reloadData()
69
- {
70
- $this->data = $this->getDataProvider()->getData();
71
- return $this->data;
72
- }
73
-
74
- /**
75
- * set data provider
76
- *
77
- * @param FACTFinder_Abstract_DataProvider
78
- * @return void
79
- **/
80
- public function setDataProvider(FACTFinder_Abstract_DataProvider $dataProvider)
81
- {
82
- $this->dataProvider = $dataProvider;
83
- }
84
-
85
- /**
86
- * get data provider
87
- *
88
- * @return FACTFinder_Abstract_DataProvider
89
- **/
90
- protected function getDataProvider()
91
- {
92
- return $this->dataProvider;
93
- }
94
-
95
- /**
96
- * set parameter parser
97
- *
98
- * @param FACTFinder_ParametersParser $paramsParser
99
- */
100
- public function setParamsParser(FACTFinder_ParametersParser $paramsParser)
101
- {
102
- $this->paramsParser = $paramsParser;
103
- }
104
-
105
- /**
106
- * returns the used factfinder params object.
107
- *
108
- * @return FACTFinder_ParametersParser
109
- **/
110
- protected function getParamsParser()
111
- {
112
- return $this->paramsParser;
113
- }
114
-
115
- /**
116
- * set encoding handler
117
- *
118
- * @param FACTFinder_EncodingHandler $encodingHandler
119
- */
120
- public function setEncodingHandler(FACTFinder_EncodingHandler $encodingHandler)
121
- {
122
- $this->encodingHandler = $encodingHandler;
123
- }
124
-
125
- /**
126
- * returns the used encoding handler
127
- *
128
- * @return FACTFinder_EncodingHandler
129
- **/
130
- protected function getEncodingHandler()
131
- {
132
- return $this->encodingHandler;
133
- }
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Abstract/Configuration.php DELETED
@@ -1,223 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Abstract
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * interface to access the needed configuration values
12
- *
13
- * @package FACTFinder\Abstract
14
- */
15
- interface FACTFinder_Abstract_Configuration
16
- {
17
- /**
18
- * @return string
19
- */
20
- function getVersion();
21
-
22
- /**
23
- * @param string name
24
- * @return string value
25
- */
26
- function getCustomValue($name);
27
-
28
- /**
29
- * @return string
30
- */
31
- function getRequestProtocol();
32
-
33
- /**
34
- * @return string
35
- */
36
- function getServerAddress();
37
-
38
- /**
39
- * @return int
40
- */
41
- function getServerPort();
42
-
43
- /**
44
- * @return string
45
- */
46
- function getContext();
47
-
48
- /**
49
- * @return string
50
- */
51
- function getChannel();
52
-
53
- /**
54
- * @return string
55
- */
56
- function getLanguage();
57
-
58
- /**
59
- * @return string
60
- */
61
- function getAuthUser();
62
-
63
- /**
64
- * @return string
65
- */
66
- function getAuthPasswort();
67
-
68
- /**
69
- * @return boolean
70
- */
71
- function isHttpAuthenticationType();
72
-
73
- /**
74
- * @return boolean
75
- */
76
- function isSimpleAuthenticationType();
77
-
78
- /**
79
- * @return boolean
80
- */
81
- function isAdvancedAuthenticationType();
82
-
83
- /**
84
- * @return string
85
- */
86
- function getAdvancedAuthPrefix();
87
-
88
- /**
89
- * @return string
90
- */
91
- function getAdvancedAuthPostfix();
92
-
93
- /**
94
- * get mapping rules to map params for the page
95
- *
96
- * @return array
97
- */
98
- function getPageMappings();
99
-
100
- /**
101
- * get mapping rules to map params for the server
102
- *
103
- * @return array
104
- */
105
- function getServerMappings();
106
-
107
- /**
108
- * returns an array of parameter names as array keys with the boolean value true. this are the ignored page
109
- * parameters from the configuration
110
- *
111
- * @return array with string as key and boolean true as value for each of them
112
- */
113
- function getIgnoredPageParams();
114
-
115
- /**
116
- * returns an array of parameter names as array keys with the boolean value true. this are the ignored server
117
- * parameters from the configuration
118
- *
119
- * @return array with string as key and boolean true as value for each of them
120
- */
121
- function getIgnoredServerParams();
122
-
123
- /**
124
- * returns an array of the required parameters for the page. The array-keys are the parameter names and the array
125
- * values are the default values of each parameter
126
- *
127
- * @return array string to string map (param-name as array-key; default value as array-value)
128
- */
129
- function getRequiredPageParams();
130
-
131
- /**
132
- * returns an array of the required parameters for the server. The array-keys are the parameter names and the array
133
- * values are the default values of each parameter
134
- *
135
- * @return array string to string map (param-name as array-key; default value as array-value)
136
- */
137
- function getRequiredServerParams();
138
-
139
- /**
140
- * get default connect timeout for all adapters
141
- *
142
- * @return string
143
- **/
144
-
145
- function getDefaultConnectTimeout();
146
-
147
- /**
148
- * get default timeout for all adapters
149
- *
150
- * @return string
151
- **/
152
-
153
- function getDefaultTimeout();
154
-
155
- /**
156
- * get connect timeout for suggest adapter
157
- *
158
- * @return string
159
- **/
160
-
161
- function getSuggestConnectTimeout();
162
-
163
- /**
164
- * get timeout for suggest adapter
165
- *
166
- * @return string
167
- **/
168
-
169
- function getSuggestTimeout();
170
-
171
- /**
172
- * get connect timeout for scic adapter
173
- *
174
- * @return string
175
- **/
176
-
177
- function getScicConnectTimeout();
178
-
179
- /**
180
- * get timeout for scic adapter
181
- *
182
- * @return string
183
- **/
184
-
185
- function getScicTimeout();
186
-
187
- /**
188
- * get connect timeout for import adapter
189
- *
190
- * @return string
191
- **/
192
-
193
- function getImportConnectTimeout();
194
-
195
- /**
196
- * get timeout for import adapter
197
- *
198
- * @return string
199
- **/
200
-
201
- function getImportTimeout();
202
-
203
- /**
204
- * get encoding of the page content
205
- *
206
- * @return string
207
- */
208
- function getPageContentEncoding();
209
-
210
- /**
211
- * get encoding of the page url
212
- *
213
- * @return string
214
- */
215
- function getPageUrlEncoding();
216
-
217
- /**
218
- * get encoding of the server url
219
- *
220
- * @return string
221
- */
222
- function getServerUrlEncoding();
223
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Abstract/DataProvider.php DELETED
@@ -1,125 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Abstract
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * abstract data provider
12
- *
13
- * @author Rudolf Batt <rb@omikron.net>
14
- * @version $Id: DataProvider.php 25893 2010-06-29 08:19:43Z rb $
15
- * @package FACTFinder\Abstract
16
- */
17
- abstract class FACTFinder_Abstract_DataProvider
18
- {
19
- protected $params = array();
20
- protected $config = array();
21
- protected $type;
22
-
23
- protected $log;
24
-
25
- public function __construct(array $params = null, FACTFinder_Abstract_Configuration $config = null,
26
- FACTFinder_Abstract_Logger $log = null)
27
- {
28
- if(isset($log))
29
- $this->log = $log;
30
- else
31
- $this->log = FF::getSingleton('nullLogger');
32
- $this->log->info("Initializing data provider.");
33
- if ($params != null) $this->setParams($params);
34
- if ($config != null) $this->setConfig($config);
35
- }
36
-
37
- /**
38
- * set type to identify which data should be loaded. that could be a request path or any source identifier
39
- *
40
- * @param mixed target
41
- **/
42
- public function setType($type)
43
- {
44
- $this->type = $type;
45
- }
46
-
47
- /**
48
- * return the data for the current config and params; the return type depends on the implementation
49
- *
50
- * @return mixed data
51
- **/
52
- abstract public function getData();
53
-
54
- /**
55
- * sets factfinder params object
56
- *
57
- * @param array params
58
- * @return void
59
- **/
60
- public function setParams(array $params)
61
- {
62
- $this->params = $params;
63
- }
64
-
65
- /**
66
- * set single param
67
- *
68
- * @param string name
69
- * @param string value
70
- * @return void
71
- **/
72
- public function setParam($name, $value)
73
- {
74
- $this->params[$name] = $value;
75
- }
76
-
77
- /**
78
- * unset single param
79
- *
80
- * @param string name
81
- * @return void
82
- **/
83
- public function unsetParam($name)
84
- {
85
- unset($this->params[$name]);
86
- }
87
-
88
- /**
89
- * set single param with multiple values
90
- *
91
- * @param string name
92
- * @param array of strings values
93
- * @return void
94
- **/
95
- public function setArrayParam($name, $values)
96
- {
97
- $this->params[$name] = $values;
98
- }
99
-
100
- /**
101
- * @param FACTFinder_Abstract_IConfiguration config
102
- **/
103
- public function setConfig(FACTFinder_Abstract_Configuration $config)
104
- {
105
- $this->config = $config;
106
- }
107
-
108
- /**
109
- * @return array
110
- **/
111
- public function getParams()
112
- {
113
- return $this->params;
114
- }
115
-
116
- /**
117
- * This is public, so that adapters don't need their own config objects.
118
- *
119
- * @return FACTFinder_Abstract_IConfiguration
120
- **/
121
- public function getConfig()
122
- {
123
- return $this->config;
124
- }
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Abstract/Logger.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Abstract
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * interface to access a logger if needed
12
- *
13
- * @package FACTFinder\Abstract
14
- */
15
- interface FACTFinder_Abstract_Logger
16
- {
17
- public function trace($message);
18
- public function debug($message);
19
- public function info($message);
20
- public function warn($message);
21
- public function error($message);
22
- public function fatal($message);
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Adapter/AbstractAdapter.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Base class for all adapters. An adapter is a class that configures a request
8
+ * to some FACT-Finder action and transforms the result into useful domain
9
+ * objects (usually objects of classes from the \Data namespace).
10
+ * The adapter classes could conceivably be placed in the \Core\Server
11
+ * namespace, but that would potentially discourage fiddling with and extending
12
+ * these classes. The adapters are main components of the external API of this
13
+ * library. Most other classes are just used to make the adapters work.
14
+ */
15
+ abstract class AbstractAdapter
16
+ {
17
+ /**
18
+ * @var \FACTFinder\Util\LoggerInterface
19
+ */
20
+ private $log;
21
+
22
+ /**
23
+ * @var \FACTFinder\Core\ConfigurationInterface
24
+ */
25
+ protected $configuration;
26
+
27
+ /**
28
+ * @var \FACTFinder\Core\Server\Request
29
+ */
30
+ protected $request;
31
+
32
+ /**
33
+ * @var FACTFinder\Util\Parameters
34
+ */
35
+ protected $parameters;
36
+
37
+ /**
38
+ * @var \FACTFinder\Core\Client\UrlBuilder
39
+ */
40
+ protected $urlBuilder;
41
+
42
+ /**
43
+ * @var \FACTFinder\Util\ContentProcessorInterface
44
+ */
45
+ private $responseContentProcessor;
46
+
47
+ /**
48
+ * @var \FACTFinder\Core\Server\Response
49
+ */
50
+ private $lastResponse = null;
51
+
52
+ /**
53
+ * @var object The processed response content.
54
+ */
55
+ private $responseContent = null;
56
+
57
+ /**
58
+ * @param string $loggerClass Class name of logger to use. The class should
59
+ * implement FACTFinder\Util\LoggerInterface.
60
+ * @param \FACTFinder\Core\ConfigurationInterface $configuration
61
+ * Configuration object to use.
62
+ * @param \FACTFinder\Core\Server\Request $request The request object from
63
+ * which to obtain the server data.
64
+ * @param \FACTFinder\Core\Client\UrlBuilder $urlBuilder
65
+ * Client URL builder object to use.
66
+ * @param \FACTFinder\Core\encodingConverter $encodingConverter
67
+ * Encoding converter object to use
68
+ */
69
+ public function __construct(
70
+ $loggerClass,
71
+ \FACTFinder\Core\ConfigurationInterface $configuration,
72
+ \FACTFinder\Core\Server\Request $request,
73
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
74
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
75
+ ) {
76
+ $this->log = $loggerClass::getLogger(__CLASS__);
77
+ $this->configuration = $configuration;
78
+ $this->request = $request;
79
+ $this->parameters = $request->getParameters();
80
+ $this->urlBuilder = $urlBuilder;
81
+ $this->encodingConverter = $encodingConverter;
82
+
83
+ $this->usePassthroughResponseContentProcessor();
84
+ }
85
+
86
+ protected function usePassthroughResponseContentProcessor()
87
+ {
88
+ $this->responseContentProcessor = function($string) {
89
+ return $string;
90
+ };
91
+ }
92
+
93
+ protected function useJsonResponseContentProcessor()
94
+ {
95
+ $this->responseContentProcessor = function($string) {
96
+
97
+ // The second parameter turns objects into associative arrays.
98
+ // stdClass objects don't really have any advantages over plain
99
+ // arrays but miss out on some of the built-in array functions.
100
+ $jsonData = json_decode($string, true);
101
+
102
+ if (is_null($jsonData))
103
+ throw new \InvalidArgumentException(
104
+ "json_decode() raised an error: ".json_last_error()
105
+ );
106
+
107
+ if(is_array($jsonData) && isset($jsonData['error'])) {
108
+ $this->log->error("FACT-Finder returned error: " . strip_tags($jsonData['error']));
109
+ if(isset($jsonData['stacktrace'])) {
110
+ $this->log->error("Stacktrace:\n" . $jsonData['stacktrace']);
111
+ }
112
+ }
113
+ return $jsonData;
114
+ };
115
+ }
116
+
117
+ protected function useXmlResponseContentProcessor()
118
+ {
119
+ $this->responseContentProcessor = function($string) {
120
+ libxml_use_internal_errors(true);
121
+ // The constructor throws an exception on error
122
+ $response = new \SimpleXMLElement($string);
123
+ if(isset($response->error)) {
124
+ $this->log->error("FACT-Finder returned error: " . strip_tags($response->error));
125
+ if(isset($response->stacktrace)) {
126
+ $this->log->error("Stacktrace:\n" . $response->stacktrace);
127
+ }
128
+ }
129
+ return $response;
130
+ };
131
+ }
132
+
133
+ /**
134
+ * Pass in a function to process the response content. This method is not
135
+ * used within the library, but may be convenient when writing custom
136
+ * adapters.
137
+ *
138
+ * @param object $callable A function (or invokable object) that processes
139
+ * a single string parameter.
140
+ *
141
+ * @throws InvalidArgumentException if $callable is not callable.
142
+ */
143
+ protected function useResponseContentProcessor($callable)
144
+ {
145
+ // Check shamelessly stolen from Pimple.php
146
+ if (!method_exists($callable, '__invoke'))
147
+ throw new \InvalidArgumentException('Content processor is neither a Closure or invokable object.');
148
+
149
+ $this->responseContentProcessor = $callable;
150
+
151
+ // Invalidate processed response content
152
+ $this->responseContent = null;
153
+ }
154
+
155
+ protected function getResponseContent()
156
+ {
157
+ $response = $this->request->getResponse();
158
+
159
+ // Only reprocess the response content, if the response is new.
160
+ if (is_null($this->responseContent)
161
+ || $response !== $this->lastResponse
162
+ ) {
163
+ $content = $response->getContent();
164
+
165
+ // PHP does not (yet?) support $this->method($args) for callable
166
+ // properties
167
+
168
+ if($content !== null) {
169
+ $this->responseContent = $this->responseContentProcessor->__invoke($content);
170
+ if ($this->encodingConverter != null)
171
+ {
172
+ $this->responseContent = $this->encodingConverter->encodeContentForPage($this->responseContent);
173
+ }
174
+ } else {
175
+ $this->responseContent = array();
176
+ }
177
+
178
+ $this->lastResponse = $response;
179
+ }
180
+
181
+ return $this->responseContent;
182
+ }
183
+
184
+ protected function convertServerQueryToClientUrl($query)
185
+ {
186
+ $parameters = FF::getInstance(
187
+ 'Util\Parameters',
188
+ $query,
189
+ true
190
+ );
191
+
192
+ return $this->urlBuilder->generateUrl($parameters);
193
+ }
194
+ }
lib/FACTFinder/Adapter/Compare.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class Compare extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ /**
14
+ * @var mixed[]
15
+ * @see getSimilarAttributes()
16
+ */
17
+ private $comparableAttributes;
18
+
19
+ /**
20
+ * @var FACTFinder\Data\Result
21
+ */
22
+ private $comparedRecords;
23
+
24
+ /**
25
+ * @var bool
26
+ */
27
+ private $attributesUpToDate = false;
28
+ private $recordsUpToDate = false;
29
+
30
+ /**
31
+ * @var bool
32
+ */
33
+ private $comparableAttributesOnly = false;
34
+
35
+
36
+ public function __construct(
37
+ $loggerClass,
38
+ \FACTFinder\Core\ConfigurationInterface $configuration,
39
+ \FACTFinder\Core\Server\Request $request,
40
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
41
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
42
+ ) {
43
+ parent::__construct($loggerClass, $configuration, $request,
44
+ $urlBuilder, $encodingConverter);
45
+
46
+ $this->log = $loggerClass::getLogger(__CLASS__);
47
+
48
+ $this->request->setAction('Compare.ff');
49
+ $this->parameters['format'] = 'json';
50
+
51
+ $this->useJsonResponseContentProcessor();
52
+ }
53
+
54
+ /**
55
+ * Set a list-like array of product IDs to compare.
56
+ *
57
+ * @param string[] $productIDs
58
+ */
59
+ public function setProductIDs($productIDs)
60
+ {
61
+ $parameters = $this->request->getParameters();
62
+ $parameters['ids'] = implode(';', $productIDs);
63
+ $this->attributesUpToDate = false;
64
+ $this->recordsUpToDate = false;
65
+ }
66
+
67
+ /**
68
+ * Set this to true to only retrieve those attributes that have been used
69
+ * for comparison instead of full Record objects.
70
+ *
71
+ * @param $comparableAttributesOnly bool
72
+ */
73
+ public function setComparableAttributesOnly($comparableAttributesOnly)
74
+ {
75
+ // Reset the compared products, if more detail is wanted than before
76
+ if($this->comparableAttributesOnly && !$comparableAttributesOnly)
77
+ $this->recordsUpToDate = false;
78
+
79
+ $this->comparableAttributesOnly = $comparableAttributesOnly;
80
+ $parameters = $this->request->getParameters();
81
+ $parameters['idsOnly'] = $comparableAttributesOnly ? 'true' : 'false';
82
+ }
83
+
84
+ /**
85
+ * Returns the attributes which can be compared and whether the products in
86
+ * question differ in each of those attributes. If no IDs have been set,
87
+ * there will be a warning raised and an empty array will be returned.
88
+ *
89
+ * @return bool[] Attribute names as keys, boolean value indicates whether
90
+ * products have different values for this attribute.
91
+ */
92
+ public function getComparableAttributes()
93
+ {
94
+ if (is_null($this->comparableAttributes)
95
+ || !$this->attributesUpToDate
96
+ ) {
97
+ $this->comparableAttributes = $this->createComparableAttributes();
98
+ $this->attributesUpToDate = true;
99
+ }
100
+
101
+ return $this->comparableAttributes;
102
+ }
103
+
104
+ private function createComparableAttributes()
105
+ {
106
+ $attributes = array();
107
+
108
+ $parameters = $this->request->getParameters();
109
+ if (!isset($parameters['ids']))
110
+ {
111
+ $this->log->warn('Comparable attributes cannot be loaded without product IDs. '
112
+ . 'Use setProductIDs() first.');
113
+ }
114
+ else
115
+ {
116
+ $jsonData = $this->getResponseContent();
117
+ foreach($jsonData['attributes'] as $attributeData)
118
+ {
119
+ $name = $attributeData['attributeName'];
120
+ $attributes[$name] = $attributeData['different'];
121
+ }
122
+ }
123
+
124
+ return $attributes;
125
+ }
126
+
127
+ /**
128
+ * Returns the records corresponding to the IDs previously specified. If no
129
+ * IDs have been set, there will be a warning raised and an empty result
130
+ * will be returned.
131
+ *
132
+ * @return \FACTFinder\Data\Result
133
+ */
134
+ public function getComparedRecords()
135
+ {
136
+ if (is_null($this->comparedRecords)
137
+ || !$this->recordsUpToDate
138
+ ) {
139
+ $this->comparedRecords = $this->createComparedRecords();
140
+ $this->recordsUpToDate = true;
141
+ }
142
+
143
+ return $this->comparedRecords;
144
+ }
145
+
146
+ private function createComparedRecords()
147
+ {
148
+ $records = array();
149
+
150
+ $parameters = $this->request->getParameters();
151
+ if (!isset($parameters['ids']))
152
+ {
153
+ $this->log->warn('Compared records cannot be loaded without product IDs. '
154
+ . 'Use setProductIDs() first.');
155
+ }
156
+ else
157
+ {
158
+ $position = 1;
159
+ $jsonData = $this->getResponseContent();
160
+ foreach($jsonData['records'] as $recordData)
161
+ {
162
+ $records[] = FF::getInstance(
163
+ 'Data\Record',
164
+ (string)$recordData['id'],
165
+ $recordData['record'],
166
+ 100.0,
167
+ $position++
168
+ );
169
+ }
170
+ }
171
+
172
+ return FF::getInstance(
173
+ 'Data\Result',
174
+ $records,
175
+ null,
176
+ count($records)
177
+ );
178
+ }
179
+ }
lib/FACTFinder/Adapter/Import.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class Import extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ public function __construct(
14
+ $loggerClass,
15
+ \FACTFinder\Core\ConfigurationInterface $configuration,
16
+ \FACTFinder\Core\Server\Request $request,
17
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
18
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
19
+ ) {
20
+ parent::__construct($loggerClass, $configuration, $request,
21
+ $urlBuilder, $encodingConverter);
22
+
23
+ $this->log = $loggerClass::getLogger(__CLASS__);
24
+
25
+ // Don't set request action yet, because it depends on the kind of
26
+ // import to be done.
27
+ $this->parameters['format'] = 'xml';
28
+
29
+ $this->request->setConnectTimeout($configuration->getImportConnectTimeout());
30
+ $this->request->setTimeout($configuration->getImportTimeout());
31
+
32
+ $this->useXmlResponseContentProcessor();
33
+ }
34
+
35
+ /**
36
+ * Trigger a search data import.
37
+ *
38
+ * @param bool $download If true, update import files prior to import.
39
+ */
40
+ public function triggerDataImport($download = false)
41
+ {
42
+ //this function changes parameters, action, ... so reload of response is neccessary
43
+ $this->request->resetLoaded();
44
+
45
+ $this->request->setAction('Import.ff');
46
+
47
+ $this->parameters['download'] = $download ? 'true' : 'false';
48
+
49
+ // TODO: Parse the response XML into some nice domain object.
50
+ return $this->getResponseContent();
51
+ }
52
+
53
+ /**
54
+ * Trigger a suggest data import.
55
+ *
56
+ * @param bool $download If true, update import files prior to import.
57
+ */
58
+ public function triggerSuggestImport($download = false)
59
+ {
60
+ //this function changes parameters, action, ... so reload of response is neccessary
61
+ $this->request->resetLoaded();
62
+
63
+ $this->request->setAction('Import.ff');
64
+
65
+ $this->parameters['download'] = $download ? 'true' : 'false';
66
+ $this->parameters['type'] = 'suggest';
67
+
68
+ $report = $this->getResponseContent();
69
+
70
+ // Clean up for next import
71
+ unset($this->parameters['type']);
72
+
73
+ // TODO: Parse the response XML into some nice domain object.
74
+ return $report;
75
+ }
76
+
77
+ /**
78
+ * Trigger a recommendation data import.
79
+ *
80
+ * @param bool $download If true, update import files prior to import.
81
+ */
82
+ public function triggerRecommendationImport($download = false)
83
+ {
84
+ //this function changes parameters, action, ... so reload of response is neccessary
85
+ $this->request->resetLoaded();
86
+
87
+ $this->request->setAction('Recommender.ff');
88
+
89
+ $this->parameters['download'] = $download ? 'true' : 'false';
90
+ $this->parameters['do'] = 'importData';
91
+
92
+ $report = $this->getResponseContent();
93
+
94
+ // Clean up for next import
95
+ unset($this->parameters['do']);
96
+
97
+ // TODO: Parse the response XML into some nice domain object.
98
+ return $report;
99
+ }
100
+ }
lib/FACTFinder/Adapter/ProductCampaign.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class ProductCampaign extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ /**
14
+ * @var FACTFinder\Data\Result
15
+ */
16
+ private $campaigns;
17
+
18
+ /**
19
+ * @var bool
20
+ */
21
+ protected $isShoppingCartCampaign = false;
22
+ private $campaignsUpToDate = false;
23
+
24
+ /**
25
+ * @var bool
26
+ */
27
+ private $idsOnly = false;
28
+
29
+ public function __construct(
30
+ $loggerClass,
31
+ \FACTFinder\Core\ConfigurationInterface $configuration,
32
+ \FACTFinder\Core\Server\Request $request,
33
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
34
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
35
+ ) {
36
+ parent::__construct($loggerClass, $configuration, $request,
37
+ $urlBuilder, $encodingConverter);
38
+
39
+ $this->log = $loggerClass::getLogger(__CLASS__);
40
+
41
+ $this->request->setAction('ProductCampaign.ff');
42
+ $this->parameters['do'] = 'getProductCampaigns';
43
+ $this->parameters['format'] = 'json';
44
+
45
+ $this->useJsonResponseContentProcessor();
46
+ }
47
+
48
+ /**
49
+ * Set one or multiple product numbers to get campaigns for, overwriting any
50
+ * numbers previously set. Note that multiple numbers will only be considered for
51
+ * shopping cart campaigns. For product detail campaigns only the first number
52
+ * will be used.
53
+ *
54
+ * @param string|string[] $productNumbers One or more product numbers.
55
+ */
56
+ public function setProductNumbers($productNumbers)
57
+ {
58
+ $parameters = $this->request->getParameters();
59
+ $parameters['productNumber'] = $productNumbers;
60
+ $this->campaignsUpToDate = false;
61
+ }
62
+
63
+ /**
64
+ * For product campaigns, FACT-Finder needs the product numbers - not the IDs.
65
+ *
66
+ * @deprecated use setProductNumbers instead
67
+ * @param string|string[] $productIDs
68
+ */
69
+ public function setProductIDs($productIDs)
70
+ {
71
+ // preserve the previous logic
72
+ $this->setProductNumbers($productIDs);
73
+ }
74
+
75
+ /**
76
+ * Add one or multiple product numbser to get campaigns for, in addition to any
77
+ * numbers previously set.
78
+ *
79
+ * @param string|string[] $productNumbers One or more product numbers.
80
+ */
81
+ public function addProductNumbers($productNumbers)
82
+ {
83
+ $parameters = $this->request->getParameters();
84
+ $parameters->add('productNumber', $productNumbers);
85
+ $this->campaignsUpToDate = false;
86
+ }
87
+
88
+ /**
89
+ * For product campaigns, FACT-Finder needs the product numbers - not the IDs.
90
+ *
91
+ * @deprecated use addProductNumbers instead
92
+ * @param string|string[] $productIDs
93
+ */
94
+ public function addProductIDs($productIDs)
95
+ {
96
+ $this->addProductNumbers($productIDs);
97
+ }
98
+
99
+ /**
100
+ * Set this to true to only retrieve the IDs of pushed products instead
101
+ * of full Record objects.
102
+ *
103
+ * @param $idsOnly bool
104
+ */
105
+ public function setIDsOnly($idsOnly)
106
+ {
107
+ if($this->idsOnly && !$idsOnly)
108
+ $this->campaignsUpToDate = false;
109
+
110
+ $this->idsOnly = $idsOnly;
111
+ $parameters = $this->request->getParameters();
112
+ $parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
113
+ }
114
+
115
+ /**
116
+ * Sets the adapter up for fetching campaigns on product detail pages
117
+ */
118
+ public function makeProductCampaign()
119
+ {
120
+ $this->isShoppingCartCampaign = false;
121
+ $this->campaignsUpToDate = false;
122
+ $this->parameters['do'] = 'getProductCampaigns';
123
+ }
124
+
125
+ /**
126
+ * Sets the adapter up for fetching campaigns on shopping cart pages
127
+ */
128
+ public function makeShoppingCartCampaign()
129
+ {
130
+ $this->isShoppingCartCampaign = true;
131
+ $this->campaignsUpToDate = false;
132
+ $this->parameters['do'] = 'getShoppingCartCampaigns';
133
+ }
134
+
135
+ /**
136
+ * Returns campaigns for IDs previously specified. If no IDs have been
137
+ * set, there will be a warning raised and an empty result will be returned.
138
+ *
139
+ * @return \FACTFinder\Data\Result
140
+ */
141
+ public function getCampaigns()
142
+ {
143
+ if (is_null($this->campaigns)
144
+ || !$this->campaignsUpToDate
145
+ ) {
146
+ $this->request->resetLoaded();
147
+ $this->campaigns = $this->createCampaigns();
148
+ $this->campaignsUpToDate = true;
149
+ }
150
+
151
+ return $this->campaigns;
152
+ }
153
+
154
+ private function createCampaigns()
155
+ {
156
+ $campaigns = array();
157
+
158
+ if (!isset($this->parameters['productNumber']))
159
+ {
160
+ $this->log->warn('Product campaigns cannot be loaded without a product ID. '
161
+ . 'Use setProductIDs() or addProductIDs() first.');
162
+ }
163
+ else
164
+ {
165
+ if ($this->isShoppingCartCampaign)
166
+ {
167
+ $jsonData = $this->getResponseContent();
168
+ }
169
+ else
170
+ {
171
+ // Use only the first product ID
172
+ $productIDs = $this->parameters['productNumber'];
173
+ if (is_array($productIDs))
174
+ $this->parameters['productNumber'] = $productIDs[0];
175
+
176
+ $jsonData = $this->getResponseContent();
177
+
178
+ // Restore IDs
179
+ $this->parameters['productNumber'] = $productIDs;
180
+ }
181
+
182
+ foreach ($jsonData as $campaignData) {
183
+ $campaign = $this->createEmptyCampaignObject($campaignData);
184
+
185
+ $this->fillCampaignWithFeedback($campaign, $campaignData);
186
+ $this->fillCampaignWithPushedProducts($campaign, $campaignData);
187
+
188
+ $campaigns[] = $campaign;
189
+ }
190
+ }
191
+
192
+ $campaignIterator = FF::getInstance(
193
+ 'Data\CampaignIterator',
194
+ $campaigns
195
+ );
196
+ return $campaignIterator;
197
+ }
198
+
199
+ /**
200
+ * @param mixed[] $campaignData An associative array corresponding to the
201
+ * JSON for a single campaign.
202
+ * @return \FACTFinder\Data\Campaign
203
+ */
204
+ private function createEmptyCampaignObject(array $campaignData)
205
+ {
206
+ return FF::getInstance(
207
+ 'Data\Campaign',
208
+ $campaignData['name'],
209
+ $campaignData['category'],
210
+ $campaignData['target']['destination']
211
+ );
212
+ }
213
+
214
+ /**
215
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
216
+ * filled.
217
+ * @param mixed[] $campaignData An associative array corresponding to the
218
+ * JSON for that campaign.
219
+ */
220
+ protected function fillCampaignWithFeedback(
221
+ \FACTFinder\Data\Campaign $campaign,
222
+ array $campaignData
223
+ ) {
224
+ if (!empty($campaignData['feedbackTexts']))
225
+ {
226
+ $feedback = array();
227
+
228
+ foreach ($campaignData['feedbackTexts'] as $feedbackData)
229
+ {
230
+ // If present, add the feedback to both the label and the ID.
231
+ $html = $feedbackData['html'];
232
+ $text = $feedbackData['text'];
233
+ if (!$html)
234
+ {
235
+ $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
236
+ }
237
+
238
+ $label = $feedbackData['label'];
239
+ if ($label !== '')
240
+ $feedback[$label] = $text;
241
+
242
+ $id = $feedbackData['id'];
243
+ if ($id !== null)
244
+ $feedback[$id] = $text;
245
+ }
246
+
247
+ $campaign->addFeedback($feedback);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
253
+ * filled.
254
+ * @param mixed[] $campaignData An associative array corresponding to the
255
+ * JSON for that campaign.
256
+ */
257
+ private function fillCampaignWithPushedProducts(
258
+ \FACTFinder\Data\Campaign $campaign,
259
+ array $campaignData
260
+ ) {
261
+ if (!empty($campaignData['pushedProductsRecords']))
262
+ {
263
+ $pushedProducts = array();
264
+
265
+ foreach ($campaignData['pushedProductsRecords'] as $recordData)
266
+ {
267
+ $pushedProducts[] = FF::getInstance(
268
+ 'Data\Record',
269
+ (string)$recordData['id'],
270
+ $recordData['record']
271
+ );
272
+ }
273
+
274
+ $campaign->addPushedProducts($pushedProducts);
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Get the product campaigns from FACT-Finder as the string returned by the
280
+ * server.
281
+ *
282
+ * @param string $format Optional. Either 'json' or 'jsonp'. Use to
283
+ * overwrite the 'format' parameter.
284
+ * @param string $callback Optional name to overwrite the 'callback'
285
+ * parameter, which determines the name of the
286
+ * callback the response is wrapped in.
287
+ *
288
+ * @return string
289
+ */
290
+ public function getRawProductCampaigns($format = null, $callback = null)
291
+ {
292
+ $this->usePassthroughResponseContentProcessor();
293
+
294
+ if (!is_null($format))
295
+ $this->parameters['format'] = $format;
296
+ if (!is_null($callback))
297
+ $this->parameters['callback'] = $callback;
298
+
299
+ return $this->getResponseContent();
300
+ }
301
+ }
lib/FACTFinder/Adapter/Recommendation.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class Recommendation extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ /**
14
+ * @var FACTFinder\Data\Result
15
+ */
16
+ private $recommendations;
17
+
18
+ /**
19
+ * @var bool
20
+ */
21
+ private $recommendationsUpToDate = false;
22
+
23
+ /**
24
+ * @var bool
25
+ */
26
+ private $idsOnly = false;
27
+
28
+
29
+ public function __construct(
30
+ $loggerClass,
31
+ \FACTFinder\Core\ConfigurationInterface $configuration,
32
+ \FACTFinder\Core\Server\Request $request,
33
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
34
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
35
+ ) {
36
+ parent::__construct($loggerClass, $configuration, $request,
37
+ $urlBuilder, $encodingConverter);
38
+
39
+ $this->log = $loggerClass::getLogger(__CLASS__);
40
+
41
+ $this->request->setAction('Recommender.ff');
42
+ $this->parameters['do'] = 'getRecommendation';
43
+ $this->parameters['format'] = 'json';
44
+
45
+ $this->useJsonResponseContentProcessor();
46
+ }
47
+
48
+
49
+ /**
50
+ * Set the maximum amount of recommendations to be fetched.
51
+ *
52
+ * @param int $recordCount The number of records to be fetched. Something
53
+ * else than a positive integer is passed, the record count will be
54
+ * unlimited (or determined by FACT-Finder).
55
+ */
56
+ public function setRecordCount($recordCount)
57
+ {
58
+ $parameters = $this->request->getParameters();
59
+ if (is_numeric($recordCount)
60
+ && (int)$recordCount == (float)$recordCount // Is integer?
61
+ && $recordCount > 0
62
+ ) {
63
+ $parameters['maxResults'] = $recordCount;
64
+ }
65
+ else
66
+ {
67
+ unset($parameters['maxResults']);
68
+ }
69
+ // Make sure that the recommendations are fetched again. In theory,
70
+ // we only have to do this when recordCount increases.
71
+ $this->recommendationsUpToDate = false;
72
+ }
73
+
74
+ /**
75
+ * Set one or multiple product IDs to base recommendation on, overwriting
76
+ * any IDs previously set.
77
+ *
78
+ * @param string|string[] $productIDs One or more product IDs.
79
+ */
80
+ public function setProductIDs($productIDs)
81
+ {
82
+ $parameters = $this->request->getParameters();
83
+ $parameters['id'] = $productIDs;
84
+ $this->recommendationsUpToDate = false;
85
+ }
86
+
87
+ /**
88
+ * Add one or multiple product IDs to base recommendation on, in addition to
89
+ * any IDs previously set.
90
+ *
91
+ * @param string|string[] $productIDs One or more product IDs.
92
+ */
93
+ public function addProductIDs($productIDs)
94
+ {
95
+ $parameters = $this->request->getParameters();
96
+ $parameters->add('id', $productIDs);
97
+ $this->recommendationsUpToDate = false;
98
+ }
99
+
100
+ /**
101
+ * Set this to true to only retrieve the IDs of recommended products instead
102
+ * of full Record objects.
103
+ * @param $idsOnly bool
104
+ */
105
+ public function setIdsOnly($idsOnly)
106
+ {
107
+ // Reset the recommendations, if more detail is wanted than before
108
+ if($this->idsOnly && !$idsOnly)
109
+ $this->recommendationsUpToDate = false;
110
+
111
+ $this->idsOnly = $idsOnly;
112
+ $parameters = $this->request->getParameters();
113
+ $parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
114
+ }
115
+
116
+ /**
117
+ * Returns recommendations for IDs previously specified. If no IDs have been
118
+ * set, there will be a warning raised and an empty result will be returned.
119
+ *
120
+ * @return \FACTFinder\Data\Result
121
+ */
122
+ public function getRecommendations()
123
+ {
124
+ if (is_null($this->recommendations)
125
+ || !$this->recommendationsUpToDate
126
+ ) {
127
+ $this->request->resetLoaded();
128
+ $this->recommendations = $this->createRecommendations();
129
+ $this->recommendationsUpToDate = true;
130
+ }
131
+
132
+ return $this->recommendations;
133
+ }
134
+
135
+ private function createRecommendations()
136
+ {
137
+ $records = array();
138
+
139
+ $parameters = $this->request->getParameters();
140
+ if (!isset($parameters['id']))
141
+ {
142
+ $this->log->warn('Recommendations cannot be loaded without a product ID. '
143
+ . 'Use setProductIDs() or addProductIDs() first.');
144
+ }
145
+ else
146
+ {
147
+ $recommenderData = $this->getResponseContent();
148
+ if (isset($recommenderData['resultRecords']))
149
+ {
150
+ $recommenderData = $recommenderData['resultRecords'];
151
+ }
152
+ $position = 1;
153
+ foreach($recommenderData as $recordData)
154
+ {
155
+ if ($this->idsOnly)
156
+ $records[] = $this->createSparseRecord($recordData);
157
+ else
158
+ $records[] = $this->createRecord($recordData, $position++);
159
+ }
160
+ }
161
+
162
+ return FF::getInstance(
163
+ 'Data\Result',
164
+ $records,
165
+ null,
166
+ count($records)
167
+ );
168
+ }
169
+
170
+ private function createSparseRecord($recordData)
171
+ {
172
+ return FF::getInstance(
173
+ 'Data\Record',
174
+ (string)$recordData['id']
175
+ );
176
+ }
177
+
178
+ private function createRecord($recordData, $position)
179
+ {
180
+ return FF::getInstance(
181
+ 'Data\Record',
182
+ (string)$recordData['id'],
183
+ $recordData['record'],
184
+ 100.0,
185
+ $position
186
+ );
187
+ }
188
+
189
+ /**
190
+ * Get the recommendations from FACT-Finder as the string returned by the
191
+ * server.
192
+ *
193
+ * @param string $format Optional. Either 'json' or 'jsonp'. Use to
194
+ * overwrite the 'format' parameter.
195
+ * @param string $callback Optional name to overwrite the 'callback'
196
+ * parameter, which determines the name of the
197
+ * callback the response is wrapped in.
198
+ *
199
+ * @return string
200
+ */
201
+ public function getRawRecommendations($format = null, $callback = null)
202
+ {
203
+ $this->usePassthroughResponseContentProcessor();
204
+
205
+ if (!is_null($format))
206
+ $this->parameters['format'] = $format;
207
+ if (!is_null($callback))
208
+ $this->parameters['callback'] = $callback;
209
+
210
+ return $this->getResponseContent();
211
+ }
212
+ }
lib/FACTFinder/Adapter/Search.php ADDED
@@ -0,0 +1,1001 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class Search extends AbstractAdapter
7
+ {
8
+
9
+ /**
10
+ * @var FACTFinder\Util\LoggerInterface
11
+ */
12
+ private $log;
13
+
14
+ /**
15
+ * @var FACTFinder\Data\Result
16
+ */
17
+ private $result;
18
+
19
+ /**
20
+ * @var FACTFinder\Data\SingleWordSearchItem[]
21
+ */
22
+ private $singleWordSearch;
23
+
24
+ /**
25
+ * @var FACTFinder\Data\AfterSearchNavigation
26
+ */
27
+ private $afterSearchNavigation;
28
+
29
+ /**
30
+ * @var FACTFinder\Data\ResultsPerPageOptions
31
+ */
32
+ private $resultsPerPageOptions;
33
+
34
+ /**
35
+ * @var FACTFinder\Data\Paging
36
+ */
37
+ private $paging;
38
+
39
+ /**
40
+ * @var FACTFinder\Data\Sorting
41
+ */
42
+ private $sorting;
43
+
44
+ /**
45
+ * @var FACTFinder\Data\BreadCrumbTrail
46
+ */
47
+ private $breadCrumbTrail;
48
+
49
+ /**
50
+ * @var FACTFinder\Data\CampaignIterator
51
+ */
52
+ private $campaigns;
53
+
54
+ /**
55
+ * @var bool
56
+ */
57
+ private $recordsUpToDate = false;
58
+
59
+ /**
60
+ * @var bool
61
+ */
62
+ private $idsOnly = false;
63
+
64
+ public function __construct(
65
+ $loggerClass,
66
+ \FACTFinder\Core\ConfigurationInterface $configuration,
67
+ \FACTFinder\Core\Server\Request $request,
68
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
69
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
70
+ ) {
71
+ parent::__construct($loggerClass, $configuration, $request,
72
+ $urlBuilder, $encodingConverter);
73
+
74
+ $this->log = $loggerClass::getLogger(__CLASS__);
75
+
76
+ $this->request->setAction('Search.ff');
77
+ $this->parameters['format'] = 'json';
78
+
79
+ $this->useJsonResponseContentProcessor();
80
+ }
81
+
82
+ /**
83
+ * Overwrite the query on the request.
84
+ * @param string $query
85
+ */
86
+ public function setQuery($query)
87
+ {
88
+ $this->parameters['query'] = $query;
89
+ }
90
+
91
+ /**
92
+ * Set Value for parameter sid
93
+ * @param string $sSid session id
94
+ */
95
+ public function setSid($sSid)
96
+ {
97
+ $this->parameters['sid'] = $sSid;
98
+ }
99
+
100
+ /**
101
+ * Set this to true to only retrieve the IDs of products instead
102
+ * of full Record objects.
103
+ *
104
+ * @param $idsOnly bool
105
+ */
106
+ public function setIDsOnly($idsOnly)
107
+ {
108
+ if($this->idsOnly && !$idsOnly)
109
+ $this->recordsUpToDate = false;
110
+
111
+ $this->idsOnly = $idsOnly;
112
+ $parameters = $this->request->getParameters();
113
+ $parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
114
+ }
115
+
116
+ /**
117
+ * @return \FACTFinder\Data\Result
118
+ */
119
+ public function getResult()
120
+ {
121
+ if (is_null($this->result) || !$this->recordsUpToDate) {
122
+ $this->request->resetLoaded();
123
+ $this->result = $this->createResult();
124
+ $this->recordsUpToDate = true;
125
+ }
126
+
127
+ return $this->result;
128
+ }
129
+
130
+ /**
131
+ * @return \FACTFinder\Data\Result
132
+ */
133
+ private function createResult()
134
+ {
135
+ //init default values
136
+ $records = array();
137
+ $resultCount = 0;
138
+ $refKey = null;
139
+
140
+ $jsonData = $this->getResponseContent();
141
+
142
+ if (isset($jsonData['searchResult'])) {
143
+ $searchResultData = $jsonData['searchResult'];
144
+ $refKey = $searchResultData['refKey'];
145
+
146
+ if (!empty($searchResultData['records']))
147
+ {
148
+ $resultCount = $searchResultData['resultCount'];
149
+
150
+ foreach ($searchResultData['records'] as $recordData)
151
+ {
152
+ $position = $recordData['position'];
153
+
154
+ $record = FF::getInstance('Data\Record',
155
+ (string)$recordData['id'],
156
+ $recordData['record'],
157
+ $recordData['searchSimilarity'],
158
+ $position,
159
+ isset($recordData['seoPath']) ? $recordData['seoPath'] : '',
160
+ $recordData['keywords']
161
+ );
162
+
163
+ $records[] = $record;
164
+ }
165
+ }
166
+ }
167
+
168
+ return FF::getInstance(
169
+ 'Data\Result',
170
+ $records,
171
+ $refKey,
172
+ $resultCount
173
+ );
174
+ }
175
+
176
+ /**
177
+ * @return \FACTFinder\Data\SingleWordSearchItem[]
178
+ */
179
+ public function getSingleWordSearch()
180
+ {
181
+ if (is_null($this->singleWordSearch))
182
+ $this->singleWordSearch = $this->createSingleWordSearch();
183
+
184
+ return $this->singleWordSearch;
185
+ }
186
+
187
+ /**
188
+ * @return \FACTFinder\Data\SingleWordSearchItem[]
189
+ */
190
+ private function createSingleWordSearch()
191
+ {
192
+ $singleWordSearch = array();
193
+
194
+ $jsonData = $this->getResponseContent();
195
+ if (!empty($jsonData['searchResult']['singleWordResults']))
196
+ {
197
+ foreach ($jsonData['searchResults']['singleWordResults'] as $swsData)
198
+ {
199
+ $item = FF::getInstance(
200
+ 'Data\SingleWordSearchItem',
201
+ $swsData['word'],
202
+ $this->convertServerQueryToClientUrl(
203
+ $swsData['searchParams']
204
+ ),
205
+ $swsData['count']
206
+ );
207
+
208
+ foreach ($swsData['previewRecords'] as $recordData)
209
+ {
210
+ $item->addPreviewRecord(FF::getInstance(
211
+ 'Data\Record',
212
+ (string)$recordData['id'],
213
+ $recordData['record']
214
+ // TODO: Which are other fields are returned for preview
215
+ // records?
216
+ // TODO: Add a test for this.
217
+ ));
218
+ }
219
+
220
+ $singleWordSearch[] = $item;
221
+ }
222
+ }
223
+
224
+ return $singleWordSearch;
225
+ }
226
+
227
+ /**
228
+ * @return \FACTFinder\Data\SearchStatus
229
+ */
230
+ public function getStatus()
231
+ {
232
+ $searchStatusEnum = FF::getClassName('Data\SearchStatus');
233
+ $status = $searchStatusEnum::NoResult();
234
+
235
+ $jsonData = $this->getResponseContent();
236
+ if (isset($jsonData['searchResult']))
237
+ {
238
+ switch($jsonData['searchResult']['resultStatus'])
239
+ {
240
+ case 'nothingFound':
241
+ $status = $searchStatusEnum::EmptyResult();
242
+ break;
243
+ case 'resultsFound':
244
+ $status = $searchStatusEnum::RecordsFound();
245
+ break;
246
+ }
247
+ }
248
+ return $status;
249
+ }
250
+
251
+ /**
252
+ * @return \FACTFinder\Data\ArticleNumberSearchStatus
253
+ */
254
+ public function getArticleNumberStatus()
255
+ {
256
+ $articleNumberSearchStatusEnum = FF::getClassName('Data\ArticleNumberSearchStatus');
257
+ $status = $articleNumberSearchStatusEnum::IsNoArticleNumberSearch();
258
+
259
+ $jsonData = $this->getResponseContent();
260
+ if (isset($jsonData['searchResult']))
261
+ {
262
+ switch ($jsonData['searchResult']['resultArticleNumberStatus'])
263
+ {
264
+ case 'resultsFound':
265
+ $status = $articleNumberSearchStatusEnum::IsArticleNumberResultFound();
266
+ break;
267
+ case 'nothingFound':
268
+ $status = $articleNumberSearchStatusEnum::IsNoArticleNumberResultFound();
269
+ break;
270
+ }
271
+ }
272
+ return $status;
273
+ }
274
+
275
+ /**
276
+ * @return bool
277
+ */
278
+ public function isSearchTimedOut()
279
+ {
280
+ $jsonData = $this->getResponseContent();
281
+ if (isset($jsonData['searchResult']))
282
+ {
283
+ return $jsonData['searchResult']['timedOut'];
284
+ }
285
+ return true;
286
+ }
287
+
288
+ /**
289
+ * @return \FACTFinder\Data\AfterSearchNavigation
290
+ */
291
+ public function getAfterSearchNavigation()
292
+ {
293
+ if (is_null($this->afterSearchNavigation))
294
+ $this->afterSearchNavigation = $this->createAfterSearchNavigation();
295
+
296
+ return $this->afterSearchNavigation;
297
+ }
298
+
299
+ /**
300
+ * @return \FACTFinder\Data\AfterSearchNavigation
301
+ */
302
+ private function createAfterSearchNavigation()
303
+ {
304
+ $jsonData = $this->getResponseContent();
305
+
306
+ $filterGroups = array();
307
+
308
+ if (isset($jsonData['searchResult']['groups'])) {
309
+ foreach ($jsonData['searchResult']['groups'] as $groupData)
310
+ $filterGroups[] = $this->createFilterGroup($groupData);
311
+ }
312
+
313
+ return FF::getInstance(
314
+ 'Data\AfterSearchNavigation',
315
+ $filterGroups
316
+ );
317
+ }
318
+
319
+ /**
320
+ * @param mixed[] $groupData An associative array corresponding to the JSON
321
+ * for a single filter group.
322
+ * @return \FACTFinder\Data\FilterGroup
323
+ */
324
+ private function createFilterGroup($groupData)
325
+ {
326
+ $elements = array_merge(
327
+ $groupData['selectedElements'],
328
+ $groupData['elements']
329
+ );
330
+
331
+ $filterStyleEnum = FF::getClassName('Data\FilterStyle');
332
+ switch ($groupData['filterStyle'])
333
+ {
334
+ case 'SLIDER':
335
+ $filterStyle = $filterStyleEnum::Slider();
336
+ break;
337
+ case 'TREE':
338
+ $filterStyle = $filterStyleEnum::Tree();
339
+ break;
340
+ case 'MULTISELECT':
341
+ $filterStyle = $filterStyleEnum::MultiSelect();
342
+ break;
343
+ default:
344
+ $filterStyle = $filterStyleEnum::Regular();
345
+ break;
346
+ }
347
+
348
+ $filters = array();
349
+ foreach ($elements as $filterData)
350
+ {
351
+ if ($filterStyle == $filterStyleEnum::Slider())
352
+ $filters[] = $this->createSliderFilter($filterData);
353
+ else
354
+ $filters[] = $this->createFilter($filterData);
355
+ }
356
+
357
+ $filterSelectionType = null;
358
+ $filterSelectionTypeEnum = FF::getClassName('Data\FilterSelectionType');
359
+ if (isset($groupData['selectionType']))
360
+ {
361
+ switch ($groupData['selectionType'])
362
+ {
363
+ case 'multiSelectOr':
364
+ $filterSelectionType = $filterSelectionTypeEnum::MultiSelectOr();
365
+ break;
366
+ case 'multiSelectAnd':
367
+ $filterSelectionType = $filterSelectionTypeEnum::MultiSelectAnd();
368
+ break;
369
+ case 'singleShowUnselected':
370
+ $filterSelectionType = $filterSelectionTypeEnum::SingleShowUnselected();
371
+ break;
372
+ default:
373
+ $filterSelectionType = $filterSelectionTypeEnum::SingleHideUnselected();
374
+ break;
375
+ }
376
+ }
377
+
378
+ $filterType = null;
379
+ $filterTypeEnum = FF::getClassName('Data\FilterType');
380
+ if (isset($groupData['type']))
381
+ {
382
+ switch ($groupData['type'])
383
+ {
384
+ case 'number':
385
+ $filterType = $filterTypeEnum::Number();
386
+ break;
387
+ default:
388
+ $filterType = $filterTypeEnum::Text();
389
+ break;
390
+ }
391
+ }
392
+
393
+ return FF::getInstance(
394
+ 'Data\FilterGroup',
395
+ $filters,
396
+ $groupData['name'],
397
+ $filterStyle,
398
+ $groupData['detailedLinks'],
399
+ $groupData['unit'],
400
+ $filterSelectionType,
401
+ $filterType,
402
+ $groupData['showPreviewImages']
403
+ );
404
+ }
405
+
406
+ /**
407
+ * @param mixed[] $filterData An associative array corresponding to the JSON
408
+ * for a single filter.
409
+ * @return \FACTFinder\Data\Filter
410
+ */
411
+ private function createFilter(array $filterData)
412
+ {
413
+ $filterLink = $this->convertServerQueryToClientUrl(
414
+ $filterData['searchParams']
415
+ );
416
+
417
+ return FF::getInstance(
418
+ 'Data\Filter',
419
+ $filterData['name'],
420
+ $filterLink,
421
+ $filterData['selected'],
422
+ $filterData['associatedFieldName'],
423
+ $filterData['recordCount'],
424
+ $filterData['clusterLevel'],
425
+ $filterData['previewImageURL'] ?: ''
426
+ );
427
+ }
428
+
429
+ /**
430
+ * @param mixed[] $filterData An associative array corresponding to the JSON
431
+ * for a single slider filter.
432
+ * @return \FACTFinder\Data\SliderFilter
433
+ */
434
+ private function createSliderFilter(array $filterData)
435
+ {
436
+ // For sliders, FACT-Finder appends a filter parameter without value to
437
+ // the 'searchParams' field, which is to be filled with the selected
438
+ // minimum and maximum like 'filterValue=min-max'.
439
+ // We split that parameter off, and treat it separately to ensure that
440
+ // it stays the last parameter when converted to a client URL.
441
+ preg_match(
442
+ '/
443
+ (.*) # match and capture as much of the query as possible
444
+ [?&]filter # match "?filter" or "&filter" literally
445
+ ([^&=]*) # group 2, the field name
446
+ =(?=$|&) # make sure there is a "=" followed by the end of
447
+ # the string or another parameter
448
+ (.*) # match the remainder of the query
449
+ /x',
450
+ $filterData['searchParams'],
451
+ $matches
452
+ );
453
+
454
+ if(!empty($matches)) {
455
+ $query = $matches[1] . $matches[3];
456
+ $fieldName = $matches[2];
457
+ } else {
458
+ // The URL of searchParams was not as expected, propably the current filter was not
459
+ // added as an empty parameter. Therefore no need to remove it and we can use full searchParams URL.
460
+ $query = $filterData['searchParams'];
461
+ $fieldName = $filterData['associatedFieldName'];
462
+ }
463
+
464
+ if (urldecode($fieldName) != $filterData['associatedFieldName'])
465
+ $this->log->warn('Filter parameter of slider does not correspond '
466
+ . 'to transmitted "associatedFieldName". Parameter: '
467
+ . "$fieldName. Field name: "
468
+ . $filterData['associatedFieldName'] . '.');
469
+
470
+ $filterLink = $this->convertServerQueryToClientUrl($query);
471
+
472
+ return FF::getInstance(
473
+ 'Data\SliderFilter',
474
+ $filterLink,
475
+ $fieldName,
476
+ $filterData['absoluteMinValue'],
477
+ $filterData['absoluteMaxValue'],
478
+ $filterData['selectedMinValue'],
479
+ $filterData['selectedMaxValue']
480
+ );
481
+ }
482
+
483
+ /**
484
+ * @return \FACTFinder\Data\ResultsPerPageOptions
485
+ */
486
+ public function getResultsPerPageOptions()
487
+ {
488
+ if (is_null($this->resultsPerPageOptions))
489
+ $this->resultsPerPageOptions = $this->createResultsPerPageOptions();
490
+
491
+ return $this->resultsPerPageOptions;
492
+ }
493
+
494
+ /**
495
+ * @return \FACTFinder\Data\ResultsPerPageOptions
496
+ */
497
+ public function createResultsPerPageOptions()
498
+ {
499
+ $options = array();
500
+
501
+ $defaultOption = null;
502
+ $selectedOption = null;
503
+
504
+ $jsonData = $this->getResponseContent();
505
+
506
+ if (isset($jsonData['searchResult']))
507
+ {
508
+ $rppData = $jsonData['searchResult']['resultsPerPageList'];
509
+ if (!empty($rppData))
510
+ {
511
+ foreach ($rppData as $optionData)
512
+ {
513
+ $optionLink = $this->convertServerQueryToClientUrl(
514
+ $optionData['searchParams']
515
+ );
516
+
517
+ $option = FF::getInstance(
518
+ 'Data\Item',
519
+ $optionData['value'],
520
+ $optionLink,
521
+ $optionData['selected']
522
+ );
523
+
524
+ if ($optionData['default'])
525
+ $defaultOption = $option;
526
+ if ($optionData['selected'])
527
+ $selectedOption = $option;
528
+
529
+ $options[] = $option;
530
+ }
531
+ }
532
+ return FF::getInstance(
533
+ 'Data\ResultsPerPageOptions',
534
+ $options,
535
+ $defaultOption,
536
+ $selectedOption
537
+ );
538
+ }
539
+ return null;
540
+ }
541
+
542
+ /**
543
+ * @return \FACTFinder\Data\Paging
544
+ */
545
+ public function getPaging()
546
+ {
547
+ if (is_null($this->paging))
548
+ $this->paging = $this->createPaging();
549
+
550
+ return $this->paging;
551
+ }
552
+
553
+ /**
554
+ * @return \FACTFinder\Data\Paging
555
+ */
556
+ private function createPaging()
557
+ {
558
+ $pages = array();
559
+
560
+ $jsonData = $this->getResponseContent();
561
+
562
+ if (isset($jsonData['searchResult']))
563
+ {
564
+ $pagingData = $jsonData['searchResult']['paging'];
565
+ if (!empty($pagingData))
566
+ {
567
+ $currentPage = null;
568
+ $pageCount = $pagingData['pageCount'];
569
+
570
+ foreach ($pagingData['pageLinks'] as $pageData)
571
+ {
572
+ $page = $this->createPageItem($pageData);
573
+
574
+ if ($pageData['currentPage'])
575
+ $currentPage = $page;
576
+
577
+ $pages[] = $page;
578
+ }
579
+ }
580
+
581
+ if (!$currentPage)
582
+ $currentPage = FF::getInstance(
583
+ 'Data\Page',
584
+ $pagingData['currentPage'],
585
+ $pagingData['currentPage'],
586
+ '#',
587
+ true
588
+ );
589
+ return FF::getInstance(
590
+ 'Data\Paging',
591
+ $pages,
592
+ $pageCount,
593
+ $currentPage,
594
+ $this->createPageItem($pagingData['firstLink']),
595
+ $this->createPageItem($pagingData['lastLink']),
596
+ $this->createPageItem($pagingData['previousLink']),
597
+ $this->createPageItem($pagingData['nextLink'])
598
+ );
599
+ }
600
+ return null;
601
+ }
602
+
603
+
604
+ /**
605
+ * @param mixed[] $pageData An associative array corresponding to the JSON
606
+ * for a single page link.
607
+ * @return \FACTFinder\Data\Item
608
+ */
609
+ private function createPageItem(array $pageData = null)
610
+ {
611
+ if (is_null($pageData))
612
+ return null;
613
+
614
+ $pageLink = $this->convertServerQueryToClientUrl(
615
+ $pageData['searchParams']
616
+ );
617
+
618
+ return FF::getInstance(
619
+ 'Data\Page',
620
+ $pageData['number'],
621
+ $pageData['caption'],
622
+ $pageLink,
623
+ $pageData['currentPage']
624
+ );
625
+ }
626
+
627
+ /**
628
+ * @return \FACTFinder\Data\Sorting
629
+ */
630
+ public function getSorting()
631
+ {
632
+ if (is_null($this->sorting))
633
+ $this->sorting = $this->createSorting();
634
+
635
+ return $this->sorting;
636
+ }
637
+
638
+ /**
639
+ * @return \FACTFinder\Data\Sorting
640
+ */
641
+ private function createSorting()
642
+ {
643
+ $sortOptions = array();
644
+
645
+ $jsonData = $this->getResponseContent();
646
+
647
+ if (isset($jsonData['searchResult']))
648
+ {
649
+ $sortingData = $jsonData['searchResult']['sortsList'];
650
+ if (!empty($sortingData))
651
+ {
652
+ foreach ($sortingData as $optionData)
653
+ {
654
+ $optionLink = $this->convertServerQueryToClientUrl(
655
+ $optionData['searchParams']
656
+ );
657
+
658
+ $sortOptions[] = FF::getInstance(
659
+ 'Data\Item',
660
+ $optionData['description'],
661
+ $optionLink,
662
+ $optionData['selected']
663
+ );
664
+ }
665
+ }
666
+
667
+ return FF::getInstance(
668
+ 'Data\Sorting',
669
+ $sortOptions
670
+ );
671
+ }
672
+ return null;
673
+ }
674
+
675
+ /**
676
+ * @return \FACTFinder\Data\BreadCrumbTrail
677
+ */
678
+ public function getBreadCrumbTrail()
679
+ {
680
+ if (is_null($this->breadCrumbTrail))
681
+ $this->breadCrumbTrail = $this->createBreadCrumbTrail();
682
+
683
+ return $this->breadCrumbTrail;
684
+ }
685
+
686
+ /**
687
+ * @return \FACTFinder\Data\BreadCrumbTrail
688
+ */
689
+ private function createBreadCrumbTrail()
690
+ {
691
+ $breadCrumbs = array();
692
+
693
+ $jsonData = $this->getResponseContent();
694
+
695
+ if (isset($jsonData['searchResult']))
696
+ {
697
+ $breadCrumbTrailData = $jsonData['searchResult']['breadCrumbTrailItems'];
698
+ if (!empty($breadCrumbTrailData))
699
+ {
700
+ $i = 1;
701
+ foreach ($breadCrumbTrailData as $breadCrumbData)
702
+ {
703
+ $breadCrumbLink = $this->convertServerQueryToClientUrl(
704
+ $breadCrumbData['searchParams']
705
+ );
706
+
707
+ $breadCrumbTypeEnum = FF::getClassName('Data\BreadCrumbType');
708
+ if ($breadCrumbData['type'] == 'filter')
709
+ $type = $breadCrumbTypeEnum::Filter();
710
+ else
711
+ $type = $breadCrumbTypeEnum::Search();
712
+
713
+ $breadCrumbs[] = FF::getInstance(
714
+ 'Data\BreadCrumb',
715
+ $breadCrumbData['text'],
716
+ $breadCrumbLink,
717
+ $i == count($breadCrumbTrailData),
718
+ $type,
719
+ $breadCrumbData['associatedFieldName']
720
+ );
721
+
722
+ ++$i;
723
+ }
724
+ }
725
+ }
726
+
727
+ return FF::getInstance(
728
+ 'Data\BreadCrumbTrail',
729
+ $breadCrumbs
730
+ );
731
+ }
732
+
733
+ /**
734
+ * @return \FACTFinder\Data\CampaignIterator
735
+ */
736
+ public function getCampaigns()
737
+ {
738
+ if (is_null($this->campaigns))
739
+ $this->campaigns = $this->createCampaigns();
740
+
741
+ return $this->campaigns;
742
+ }
743
+
744
+ /**
745
+ * @return \FACTFinder\Data\CampaignIterator
746
+ */
747
+ private function createCampaigns()
748
+ {
749
+ $campaigns = array();
750
+ $jsonData = $this->getResponseContent();
751
+
752
+ if (isset($jsonData['searchResult']['campaigns'])) {
753
+ foreach ($jsonData['searchResult']['campaigns'] as $campaignData) {
754
+ $campaign = $this->createEmptyCampaignObject($campaignData);
755
+
756
+ $this->fillCampaignObject($campaign, $campaignData);
757
+
758
+ $campaigns[] = $campaign;
759
+ }
760
+ }
761
+
762
+ $campaignIterator = FF::getInstance(
763
+ 'Data\CampaignIterator',
764
+ $campaigns
765
+ );
766
+ return $campaignIterator;
767
+ }
768
+
769
+ /**
770
+ * @param mixed[] $campaignData An associative array corresponding to the
771
+ * JSON for a single campaign.
772
+ * @return \FACTFinder\Data\Campaign
773
+ */
774
+ private function createEmptyCampaignObject(array $campaignData)
775
+ {
776
+ return FF::getInstance(
777
+ 'Data\Campaign',
778
+ $campaignData['name'],
779
+ $campaignData['category'],
780
+ $campaignData['target']['destination']
781
+ );
782
+ }
783
+
784
+ /**
785
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
786
+ * filled.
787
+ * @param mixed[] $campaignData An associative array corresponding to the
788
+ * JSON for that campaign.
789
+ */
790
+ private function fillCampaignObject(
791
+ \FACTFinder\Data\Campaign $campaign,
792
+ array $campaignData
793
+ ) {
794
+ switch ($campaignData['flavour'])
795
+ {
796
+ case 'FEEDBACK':
797
+ $this->fillCampaignWithFeedback($campaign, $campaignData);
798
+ $this->fillCampaignWithPushedProducts($campaign, $campaignData);
799
+ break;
800
+ case 'ADVISOR':
801
+ $this->fillCampaignWithAdvisorData($campaign, $campaignData);
802
+ break;
803
+ }
804
+ }
805
+
806
+ /**
807
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
808
+ * filled.
809
+ * @param mixed[] $campaignData An associative array corresponding to the
810
+ * JSON for that campaign.
811
+ */
812
+ protected function fillCampaignWithFeedback(
813
+ \FACTFinder\Data\Campaign $campaign,
814
+ array $campaignData
815
+ ) {
816
+ if (!empty($campaignData['feedbackTexts']))
817
+ {
818
+ $feedback = array();
819
+
820
+ foreach ($campaignData['feedbackTexts'] as $feedbackData)
821
+ {
822
+ // If present, add the feedback to both the label and the ID.
823
+ $html = $feedbackData['html'];
824
+ $text = $feedbackData['text'];
825
+ if (!$html)
826
+ {
827
+ $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
828
+ }
829
+
830
+ $label = $feedbackData['label'];
831
+ if ($label !== '')
832
+ $feedback[$label] = $text;
833
+
834
+ $id = $feedbackData['id'];
835
+ if ($id !== null)
836
+ $feedback[$id] = $text;
837
+ }
838
+
839
+ $campaign->addFeedback($feedback);
840
+ }
841
+ }
842
+
843
+ /**
844
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
845
+ * filled.
846
+ * @param mixed[] $campaignData An associative array corresponding to the
847
+ * JSON for that campaign.
848
+ */
849
+ private function fillCampaignWithPushedProducts(
850
+ \FACTFinder\Data\Campaign $campaign,
851
+ array $campaignData
852
+ ) {
853
+ if (!empty($campaignData['pushedProductsRecords']))
854
+ {
855
+ $pushedProducts = array();
856
+
857
+ foreach ($campaignData['pushedProductsRecords'] as $recordData)
858
+ {
859
+ $pushedProducts[] = FF::getInstance(
860
+ 'Data\Record',
861
+ (string)$recordData['id'],
862
+ $recordData['record']
863
+ );
864
+ }
865
+
866
+ $campaign->addPushedProducts($pushedProducts);
867
+ }
868
+ }
869
+
870
+ /**
871
+ * @param \FACTFinder\Data\Campaign $campaign The campaign object to be
872
+ * filled.
873
+ * @param mixed[] $campaignData An associative array corresponding to the
874
+ * JSON for that campaign.
875
+ */
876
+ private function fillCampaignWithAdvisorData(
877
+ \FACTFinder\Data\Campaign $campaign,
878
+ array $campaignData
879
+ ) {
880
+ $activeQuestions = array();
881
+
882
+ foreach ($campaignData['activeQuestions'] as $questionData)
883
+ $activeQuestions[] = $this->createAdvisorQuestion($questionData);
884
+
885
+ $campaign->addActiveQuestions($activeQuestions);
886
+
887
+ // Fetch advisor tree if it exists
888
+ $advisorTree = array();
889
+
890
+ foreach ($campaignData['activeQuestions'] as $questionData)
891
+ $activeQuestions[] = $this->createAdvisorQuestion($questionData,
892
+ true);
893
+
894
+ $campaign->addToAdvisorTree($advisorTree);
895
+ }
896
+
897
+ /**
898
+ * @param mixed[] $questionData An associative array corresponding to the
899
+ * JSON for a single advisor question.
900
+ * @param bool $recursive If this is set the entire advisor tree below this
901
+ * question will be created. Otherwise, follow-up questions of
902
+ * answers are omitted.
903
+ */
904
+ private function createAdvisorQuestion($questionData, $recursive = false)
905
+ {
906
+ $answers = array();
907
+
908
+ foreach ($questionData['answers'] as $answerData)
909
+ $answers[] = $this->createAdvisorAnswer($answerData, $recursive);
910
+
911
+ return FF::getInstance('Data\AdvisorQuestion',
912
+ $questionData['text'],
913
+ $answers
914
+ );
915
+ }
916
+
917
+ /**
918
+ * @param mixed[] $answerData An associative array corresponding to the
919
+ * JSON for a single advisor answer.
920
+ * @param bool $recursive If this is set the entire advisor tree below the
921
+ * subquestion of this ansewr will be created as well.
922
+ */
923
+ private function createAdvisorAnswer($answerData, $recursive = false)
924
+ {
925
+ $params = $this->convertServerQueryToClientUrl(
926
+ $answerData['params']
927
+ );
928
+
929
+ $followUpQuestions = array();
930
+ if ($recursive)
931
+ foreach ($answerData['questions'] as $questionData)
932
+ $followUpQuestions[] = $this->createAdvisorQuestion(
933
+ $questionData,
934
+ true
935
+ );
936
+
937
+ return FF::getInstance('Data\AdvisorAnswer',
938
+ $answerData['text'],
939
+ $params,
940
+ $followUpQuestions
941
+ );
942
+ }
943
+
944
+ /**
945
+ * @return string
946
+ */
947
+ public function getError()
948
+ {
949
+ $jsonData = $this->getResponseContent();
950
+ return isset($jsonData['error']) ? $jsonData['error'] : null;
951
+ }
952
+
953
+ /**
954
+ * @return string
955
+ */
956
+ public function getStackTrace()
957
+ {
958
+ $jsonData = $this->getResponseContent();
959
+ return isset($jsonData['stacktrace']) ? $jsonData['stacktrace'] : null;
960
+ }
961
+
962
+ /**
963
+ * Value for parameter "followSearch" for followups on initial search like filters, pagination, ...
964
+ * Either from search results searchParams, request parameters or from search results "simiFirstRecord".
965
+ * Returns 0 if no parameter "followSearch" could be acquired.
966
+ *
967
+ * @return int
968
+ */
969
+ public function getFollowSearchValue()
970
+ {
971
+ $jsonData = $this->getResponseContent();
972
+ //use searchParams of result if available
973
+ if($jsonData && $jsonData['searchResult'] && isset($jsonData['searchResult']['searchParams'])) {
974
+ $parameters = FF::getInstance(
975
+ 'Util\Parameters',
976
+ $jsonData['searchResult']['searchParams']
977
+ );
978
+ //fallback to current request
979
+ } else {
980
+ $parameters = $this->parameters;
981
+ }
982
+ $searchParameters = FF::getInstance(
983
+ 'Data\SearchParameters',
984
+ $parameters
985
+ );
986
+ $sorting = $searchParameters->getSortings();
987
+ // check if followSearch was set in request data or sent by FF in result searchParams
988
+ if($searchParameters->getFollowSearch() !== 0) {
989
+ $followSearch = $searchParameters->getFollowSearch();
990
+ // use simiFirstRecord only if result was not sorted
991
+ } elseif (empty($sorting)) {
992
+ $jsonData = $this->getResponseContent();
993
+ if($jsonData && $jsonData['searchResult'] && isset($jsonData['searchResult']['simiFirstRecord']))
994
+ $followSearch = $jsonData['searchResult']['simiFirstRecord'];
995
+ //mark as not valid
996
+ } else {
997
+ $followSearch = 0;
998
+ }
999
+ return $followSearch;
1000
+ }
1001
+ }
lib/FACTFinder/Adapter/SimilarRecords.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class SimilarRecords extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ /**
14
+ * @var mixed[]
15
+ * @see getSimilarAttributes()
16
+ */
17
+ private $similarAttributes;
18
+
19
+ /**
20
+ * @var FACTFinder\Data\Result
21
+ */
22
+ private $similarRecords;
23
+
24
+ /**
25
+ * @var bool
26
+ */
27
+ private $attributesUpToDate = false;
28
+ private $recordsUpToDate = false;
29
+
30
+ /**
31
+ * @var bool
32
+ */
33
+ private $idsOnly = false;
34
+
35
+
36
+ public function __construct(
37
+ $loggerClass,
38
+ \FACTFinder\Core\ConfigurationInterface $configuration,
39
+ \FACTFinder\Core\Server\Request $request,
40
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
41
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
42
+ ) {
43
+ parent::__construct($loggerClass, $configuration, $request,
44
+ $urlBuilder, $encodingConverter);
45
+
46
+ $this->log = $loggerClass::getLogger(__CLASS__);
47
+
48
+ $this->request->setAction('SimilarRecords.ff');
49
+ $this->parameters['format'] = 'json';
50
+
51
+ $this->useJsonResponseContentProcessor();
52
+ }
53
+
54
+
55
+ /**
56
+ * Set the maximum amount of similar records to be fetched.
57
+ *
58
+ * @param int $recordCount The number of records to be fetched. Something
59
+ * else than a positive integer is passed, the record count will be
60
+ * unlimited (or determined by FACT-Finder).
61
+ */
62
+ public function setRecordCount($recordCount)
63
+ {
64
+ $parameters = $this->request->getParameters();
65
+ if (is_numeric($recordCount)
66
+ && (int)$recordCount == (float)$recordCount // Is integer?
67
+ && $recordCount > 0
68
+ ) {
69
+ $parameters['maxRecordCount'] = $recordCount;
70
+ }
71
+ else
72
+ {
73
+ unset($parameters['maxRecordCount']);
74
+ }
75
+ // Make sure that the records are fetched again. In principle, we only
76
+ // have to do this when recordCount increases.
77
+ $this->recordsUpToDate = false;
78
+ }
79
+
80
+ /**
81
+ * Set one product IDs to get similar records for.
82
+ *
83
+ * @param string $productID
84
+ */
85
+ public function setProductID($productID)
86
+ {
87
+ $parameters = $this->request->getParameters();
88
+ $parameters['id'] = $productID;
89
+ $this->attributesUpToDate = false;
90
+ $this->recordsUpToDate = false;
91
+ }
92
+
93
+ /**
94
+ * Set this to true to only retrieve the IDs of similar products instead
95
+ * of full Record objects.
96
+ * @param $idsOnly bool
97
+ */
98
+ public function setIDsOnly($idsOnly)
99
+ {
100
+ // Reset the similar records, if more detail is wanted than before
101
+ if($this->idsOnly && !$idsOnly)
102
+ $this->recordsUpToDate = false;
103
+
104
+ $this->idsOnly = $idsOnly;
105
+ $parameters = $this->request->getParameters();
106
+ $parameters['idsOnly'] = $idsOnly ? 'true' : 'false';
107
+ }
108
+
109
+ /**
110
+ * Returns the attributes based on which similar records are determined as
111
+ * well as the source product's values of those attributes. If no ID has
112
+ * been set, there will be a warning raised and an empty array will be
113
+ * returned.
114
+ *
115
+ * @return mixed[] Attribute names as keys and attribute values as values.
116
+ */
117
+ public function getSimilarAttributes()
118
+ {
119
+ if (is_null($this->similarAttributes)
120
+ || !$this->attributesUpToDate
121
+ ) {
122
+ $this->similarAttributes = $this->createSimilarAttributes();
123
+ $this->attributesUpToDate = true;
124
+ }
125
+
126
+ return $this->similarAttributes;
127
+ }
128
+
129
+ private function createSimilarAttributes()
130
+ {
131
+ $attributes = array();
132
+
133
+ $parameters = $this->request->getParameters();
134
+ if (!isset($parameters['id']))
135
+ {
136
+ $this->log->warn('Similar attributes cannot be loaded without a product ID. '
137
+ . 'Use setProductID() first.');
138
+ }
139
+ else
140
+ {
141
+ $jsonData = $this->getResponseContent();
142
+ foreach($jsonData['attributes'] as $attributeData)
143
+ {
144
+ $attributes[$attributeData['name']] = $attributeData['value'];
145
+ }
146
+ }
147
+
148
+ return $attributes;
149
+ }
150
+
151
+ /**
152
+ * Returns similar records for the ID previously specified. If no ID has
153
+ * been set, there will be a warning raised and an empty result will be
154
+ * returned.
155
+ *
156
+ * @return \FACTFinder\Data\Result
157
+ */
158
+ public function getSimilarRecords()
159
+ {
160
+ if (is_null($this->similarRecords)
161
+ || !$this->recordsUpToDate
162
+ ) {
163
+ $this->request->resetLoaded();
164
+ $this->similarRecords = $this->createSimilarRecords();
165
+ $this->recordsUpToDate = true;
166
+ }
167
+
168
+ return $this->similarRecords;
169
+ }
170
+
171
+ private function createSimilarRecords()
172
+ {
173
+ $records = array();
174
+
175
+ $parameters = $this->request->getParameters();
176
+ if (!isset($parameters['id']))
177
+ {
178
+ $this->log->warn('Similar records cannot be loaded without a product ID. '
179
+ . 'Use setProductID() first.');
180
+ }
181
+ else
182
+ {
183
+ $position = 1;
184
+ $jsonData = $this->getResponseContent();
185
+ foreach($jsonData['records'] as $recordData)
186
+ {
187
+ if ($this->idsOnly)
188
+ $records[] = $this->createSparseRecord($recordData);
189
+ else
190
+ $records[] = $this->createRecord($recordData, $position++);
191
+ }
192
+ }
193
+
194
+ return FF::getInstance(
195
+ 'Data\Result',
196
+ $records,
197
+ null,
198
+ count($records)
199
+ );
200
+ }
201
+
202
+ private function createSparseRecord($recordData)
203
+ {
204
+ return FF::getInstance(
205
+ 'Data\Record',
206
+ (string)$recordData['id']
207
+ );
208
+ }
209
+
210
+ private function createRecord($recordData, $position)
211
+ {
212
+ return FF::getInstance(
213
+ 'Data\Record',
214
+ (string)$recordData['id'],
215
+ $recordData['record'],
216
+ 100.0,
217
+ $position
218
+ );
219
+ }
220
+ }
lib/FACTFinder/Adapter/Suggest.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * TODO: Are there any other FF 6.8 features left which we are not making use of
8
+ * yet? If so: change that.
9
+ */
10
+ class Suggest extends AbstractAdapter
11
+ {
12
+ /**
13
+ * @var FACTFinder\Util\LoggerInterface
14
+ */
15
+ private $log;
16
+
17
+ /**
18
+ * @var FACTFinder\Data\SuggestQuery[]
19
+ */
20
+ private $suggestions;
21
+
22
+ public function __construct(
23
+ $loggerClass,
24
+ \FACTFinder\Core\ConfigurationInterface $configuration,
25
+ \FACTFinder\Core\Server\Request $request,
26
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
27
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
28
+ ) {
29
+ parent::__construct($loggerClass, $configuration, $request,
30
+ $urlBuilder, $encodingConverter);
31
+
32
+ $this->log = $loggerClass::getLogger(__CLASS__);
33
+
34
+ $this->request->setAction('Suggest.ff');
35
+
36
+ $this->request->setConnectTimeout($configuration->getSuggestConnectTimeout());
37
+ $this->request->setTimeout($configuration->getSuggestTimeout());
38
+ }
39
+
40
+ /**
41
+ * Get the suggestions from FACT-Finder as an array of SuggestQuery's.
42
+ *
43
+ * @return FACTFinder\Data\SuggestQuery[]
44
+ */
45
+ public function getSuggestions()
46
+ {
47
+ if (is_null($this->suggestions))
48
+ $this->suggestions = $this->createSuggestions();
49
+
50
+ return $this->suggestions;
51
+ }
52
+
53
+ private function createSuggestions()
54
+ {
55
+ $suggestions = array();
56
+
57
+ $this->useJsonResponseContentProcessor();
58
+
59
+ if (isset($this->parameters['format']))
60
+ $oldFormat = $this->parameters['format'];
61
+
62
+ $this->parameters['format'] = 'json';
63
+ $suggestData = $this->getResponseContent();
64
+ if (!empty($suggestData))
65
+ {
66
+ if (isset($suggestData['suggestions']))
67
+ {
68
+ $suggestData = $suggestData['suggestions'];
69
+ }
70
+
71
+ foreach ($suggestData as $suggestQueryData)
72
+ {
73
+ $suggestLink = $this->convertServerQueryToClientUrl(
74
+ $suggestQueryData['searchParams']
75
+ );
76
+
77
+ $suggestAttributes = null;
78
+ if (isset($suggestQueryData['attributes'])
79
+ && is_array($suggestQueryData['attributes'])
80
+ ) {
81
+ $suggestAttributes = $suggestQueryData['attributes'];
82
+ } else {
83
+ $suggestAttributes = array();
84
+ }
85
+
86
+ $suggestions[] = FF::getInstance(
87
+ 'Data\SuggestQuery',
88
+ $suggestQueryData['name'],
89
+ $suggestLink,
90
+ $suggestQueryData['hitCount'],
91
+ $suggestQueryData['type'],
92
+ $suggestQueryData['image'],
93
+ $suggestAttributes
94
+ );
95
+ }
96
+ }
97
+
98
+ if (isset($oldFormat))
99
+ $this->parameters['format'] = $oldFormat;
100
+
101
+ return $suggestions;
102
+ }
103
+
104
+ /**
105
+ * Get the suggestions from FACT-Finder as the string returned by the
106
+ * server.
107
+ *
108
+ * @param string $format Optional. Either 'json' or 'jsonp'. Use to
109
+ * overwrite the 'format' parameter.
110
+ * @param string $callback Optional name to overwrite the 'callback'
111
+ * parameter, which determines the name of the
112
+ * callback the response is wrapped in.
113
+ *
114
+ * @return string
115
+ */
116
+ public function getRawSuggestions($format = null, $callback = null)
117
+ {
118
+ $this->usePassthroughResponseContentProcessor();
119
+
120
+ if (!is_null($format))
121
+ $this->parameters['format'] = $format;
122
+ if (!is_null($callback))
123
+ $this->parameters['callback'] = $callback;
124
+
125
+ return $this->getResponseContent();
126
+ }
127
+ }
lib/FACTFinder/Adapter/TagCloud.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ class TagCloud extends AbstractAdapter
7
+ {
8
+ /**
9
+ * @var FACTFinder\Util\LoggerInterface
10
+ */
11
+ private $log;
12
+
13
+ /**
14
+ * @var FACTFinder\Data\TagQuery[]
15
+ */
16
+ private $tagCloud;
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ private $lastRequestQuery = null;
22
+
23
+ public function __construct(
24
+ $loggerClass,
25
+ \FACTFinder\Core\ConfigurationInterface $configuration,
26
+ \FACTFinder\Core\Server\Request $request,
27
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
28
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
29
+ ) {
30
+ parent::__construct($loggerClass, $configuration, $request,
31
+ $urlBuilder, $encodingConverter);
32
+
33
+ $this->log = $loggerClass::getLogger(__CLASS__);
34
+
35
+ $this->request->setAction('TagCloud.ff');
36
+ $this->parameters['do'] = 'getTagCloud';
37
+ $this->parameters['format'] = 'json';
38
+
39
+ $this->useJsonResponseContentProcessor();
40
+ }
41
+
42
+ /**
43
+ * Get the tag cloud from FACT-Finder as an array of TagQuery's.
44
+ *
45
+ * @param
46
+ *
47
+ * @return FACTFinder\Data\TagQuery[]
48
+ */
49
+ public function getTagCloud($requestQuery = null)
50
+ {
51
+ if (is_null($this->tagCloud)
52
+ || $requestQuery != $this->lastRequestQuery
53
+ ) {
54
+ $this->tagCloud = $this->createTagCloud($requestQuery);
55
+ $this->lastRequestQuery = $requestQuery;
56
+ }
57
+
58
+ return $this->tagCloud;
59
+ }
60
+
61
+ /**
62
+ * Set the maximum amount of tag queries to be fetched.
63
+ *
64
+ * @param int $wordCount The number of tag queries to be fetched. Something
65
+ * else than a positive integer is passed, the word count will be
66
+ * unlimited (or determined by FACT-Finder).
67
+ */
68
+ public function setWordCount($wordCount)
69
+ {
70
+ $parameters = $this->request->getParameters();
71
+ if (is_numeric($wordCount)
72
+ && (int)$wordCount == (float)$wordCount // Is integer?
73
+ && $wordCount > 0
74
+ ) {
75
+ $parameters['wordCount'] = $wordCount;
76
+ }
77
+ else
78
+ {
79
+ unset($parameters['wordCount']);
80
+ }
81
+ // Make sure that the tag cloud is fetched again. In theory, we only
82
+ // have to do this when wordCount increases.
83
+ $this->tagCloud = null;
84
+ }
85
+
86
+ private function createTagCloud($requestQuery = null)
87
+ {
88
+ $tagCloud = array();
89
+
90
+ $tagCloudData = $this->getResponseContent();
91
+ if (!empty($tagCloudData))
92
+ {
93
+ foreach ($tagCloudData as $tagQueryData)
94
+ {
95
+ $query = $tagQueryData['query'];
96
+
97
+ // TODO: Once JIRA issue FF-5328 is fixed, retrieve the
98
+ // parameters from searchParams, like all other adapters
99
+ // do.
100
+ $parameters = FF::getInstance('Util\Parameters');
101
+ $parameters['query'] = $query;
102
+
103
+ $tagCloud[] = FF::getInstance(
104
+ 'Data\TagQuery',
105
+ $query,
106
+ $this->urlBuilder->generateUrl($parameters),
107
+ $requestQuery == $query,
108
+ $tagQueryData['weight'],
109
+ $tagQueryData['searchCount']
110
+ );
111
+ }
112
+ }
113
+
114
+ return $tagCloud;
115
+ }
116
+ }
lib/FACTFinder/Adapter/Tracking.php ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Adapter;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This tracking adapter uses the new Tracking Interface for 6.11
8
+ */
9
+ class Tracking extends AbstractAdapter
10
+ {
11
+ /**
12
+ * @var FACTFinder\Util\LoggerInterface
13
+ */
14
+ private $log;
15
+
16
+ public function __construct(
17
+ $loggerClass,
18
+ \FACTFinder\Core\ConfigurationInterface $configuration,
19
+ \FACTFinder\Core\Server\Request $request,
20
+ \FACTFinder\Core\Client\UrlBuilder $urlBuilder,
21
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
22
+ ) {
23
+ parent::__construct($loggerClass, $configuration, $request,
24
+ $urlBuilder, $encodingConverter);
25
+
26
+ $this->log = $loggerClass::getLogger(__CLASS__);
27
+
28
+ $this->request->setAction('Tracking.ff');
29
+
30
+ $this->request->setConnectTimeout($configuration->getTrackingConnectTimeout());
31
+ $this->request->setTimeout($configuration->getTrackingTimeout());
32
+
33
+ // $this->usePassthroughResponseContentProcessor(); (default)
34
+ }
35
+
36
+ /**
37
+ * If all needed parameters are available at the request like described in
38
+ * the documentation, just use this method to fetch the needed parameters
39
+ * and track them. Make sure to set a session id if there is no parameter
40
+ * "sid". If this argument is not set or empty and the parameter "sid" is
41
+ * not available, it will try to use session_id() to fetch one.
42
+ *
43
+ * @param string $sid session id
44
+ * @return bool Success?
45
+ */
46
+ public function doTrackingFromRequest($sid = null)
47
+ {
48
+ $this->setupTrackingFromRequest($sid);
49
+ return $this->applyTracking();
50
+ }
51
+
52
+ /**
53
+ * Use this method directly if you want to separate the setup from sending
54
+ * the request. This is particularly useful when using the
55
+ * MultiCurlRequestFactory.
56
+ */
57
+ public function setupTrackingFromRequest($sid = null)
58
+ {
59
+ if (strlen($sid) > 0)
60
+ $this->parameters['sid'] = $sid;
61
+ else if (!isset($this->parameters['sid'])
62
+ || strlen($this->parameters['sid']) == 0
63
+ ) {
64
+ $this->parameters['sid'] = session_id();
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Track a detail click on a product.
70
+ *
71
+ * @param string $id id of product
72
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
73
+ * @param string $query query which led to the product
74
+ * @param int $pos position of product in the search result
75
+ * @param string $masterid masterId of product if variant
76
+ * @param string $cookieId cookie id (optional)
77
+ * @param int $origPos original position of product in the search result. this data is delivered by FACT-Finder (optional - is set equals to $position by default)
78
+ * @param int $page page number where the product was clicked (optional - is 1 by default)
79
+ * @param float $simi similiarity of the product (optional - is 100.00 by default)
80
+ * @param string $title title of product (optional - is empty by default)
81
+ * @param int $pageSize size of the page where the product was found (optional - is 12 by default)
82
+ * @param int $origPageSize original size of the page before the user could have changed it (optional - is set equals to $page by default)
83
+ * @param string $userid id of user (optional if modul personalisation is not used)
84
+ * @return boolean $success
85
+ */
86
+ public function trackClick(
87
+ $id,
88
+ $query,
89
+ $pos,
90
+ $masterId = null,
91
+ $sid = null,
92
+ $cookieId = null,
93
+ $origPos = -1,
94
+ $page = 1,
95
+ $simi = 100.0,
96
+ $title = '',
97
+ $pageSize = 12,
98
+ $origPageSize = -1,
99
+ $userid = null
100
+ ) {
101
+ $this->setupClickTracking($id, $query, $pos, $masterId, $sid, $cookieId, $origPos, $page,
102
+ $simi, $title, $pageSize, $origPageSize, $userid);
103
+ return $this->applyTracking();
104
+ }
105
+
106
+ /**
107
+ * Use this method directly if you want to separate the setup from sending
108
+ * the request. This is particularly useful when using the
109
+ * MultiCurlRequestFactory.
110
+ */
111
+ public function setupClickTracking(
112
+ $id,
113
+ $query,
114
+ $pos,
115
+ $masterId = null,
116
+ $sid = null,
117
+ $cookieId = null,
118
+ $origPos = -1,
119
+ $page = 1,
120
+ $simi = 100.0,
121
+ $title = '',
122
+ $pageSize = 12,
123
+ $origPageSize = -1,
124
+ $userid = null
125
+ ) {
126
+ if (strlen($sid) == 0) $sid = session_id();
127
+ if ($origPos == -1) $origPos = $pos;
128
+ if ($origPageSize == -1) $origPageSize = $pageSize;
129
+ $params = array(
130
+ 'id' => $id,
131
+ 'query' => $query,
132
+ 'pos' => $pos,
133
+ 'sid' => $sid,
134
+ 'origPos' => $origPos,
135
+ 'page' => $page,
136
+ 'simi' => $simi,
137
+ 'title' => $title,
138
+ 'event' => 'click',
139
+ 'pageSize' => $pageSize,
140
+ 'origPageSize' => $origPageSize,
141
+ );
142
+
143
+ if (strlen($userid) > 0) $params['userId'] = $userid;
144
+ if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
145
+ if (strlen($masterId) > 0) $params['masterId'] = $masterId;
146
+
147
+ $this->parameters->clear();
148
+ $this->parameters->setAll($params);
149
+ }
150
+
151
+ /**
152
+ * Track a product which was added to the cart.
153
+ *
154
+ * @param string $id id of product
155
+ * @param string $masterid masterId of product if variant
156
+ * @param string $tile title of product (optional - is empty by default)
157
+ * @param string $query query which led to the product (only if module Semantic Enhancer is used)
158
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
159
+ * @param string $cookieId cookie id (optional)
160
+ * @param int $count number of items purchased for each product (optional - default 1)
161
+ * @param float $price this is the single unit price (optional)
162
+ * @param string $userid id of user (optional if modul personalisation is not used)
163
+ * @return boolean $success
164
+ */
165
+ public function trackCart(
166
+ $id,
167
+ $masterId = null,
168
+ $title = '',
169
+ $query = null,
170
+ $sid = null,
171
+ $cookieId = null,
172
+ $count = 1,
173
+ $price = null,
174
+ $userid = null
175
+ ) {
176
+ $this->setupCartTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userid);
177
+ return $this->applyTracking();
178
+ }
179
+
180
+ /**
181
+ * Use this method directly if you want to separate the setup from sending
182
+ * the request. This is particularly useful when using the
183
+ * MultiCurlRequestFactory.
184
+ */
185
+ public function setupCartTracking(
186
+ $id,
187
+ $masterId = null,
188
+ $title = '',
189
+ $query = null,
190
+ $sid = null,
191
+ $cookieId = null,
192
+ $count = 1,
193
+ $price = null,
194
+ $userid = null
195
+ ) {
196
+ if (strlen($sid) == 0) $sid = session_id();
197
+ $params = array(
198
+ 'id' => $id,
199
+ 'title' => $title,
200
+ 'sid' => $sid,
201
+ 'count' => $count,
202
+ 'event' => 'cart'
203
+ );
204
+
205
+ if (strlen($price) > 0) $params['price'] = $price;
206
+ if (strlen($userid) > 0) $params['userId'] = $userid;
207
+ if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
208
+ if (strlen($masterId) > 0) $params['masterId'] = $masterId;
209
+ if (strlen($query) > 0) $params['query'] = $query;
210
+
211
+ $this->parameters->clear();
212
+ $this->parameters->setAll($params);
213
+ }
214
+
215
+ /**
216
+ * Track a product which was purchased.
217
+ *
218
+ * @param string $id id of product
219
+ * @param string $masterid masterId of product if variant
220
+ * @param string $tile title of product (optional - is empty by default)
221
+ * @param string $query query which led to the product (only if module Semantic Enhancer is used)
222
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
223
+ * @param string $cookieId cookie id (optional)
224
+ * @param int $count number of items purchased for each product (optional - default 1)
225
+ * @param float $price this is the single unit price (optional)
226
+ * @param string $userid id of user (optional if modul personalisation is not used)
227
+ * @return boolean $success
228
+ */
229
+ public function trackCheckout(
230
+ $id,
231
+ $masterId = null,
232
+ $title = '',
233
+ $query = null,
234
+ $sid = null,
235
+ $cookieId = null,
236
+ $count = 1,
237
+ $price = null,
238
+ $userid = null
239
+ ) {
240
+ $this->setupCheckoutTracking($id, $masterId, $title, $query, $sid, $cookieId, $count, $price, $userid);
241
+ return $this->applyTracking();
242
+ }
243
+
244
+ /**
245
+ * Use this method directly if you want to separate the setup from sending
246
+ * the request. This is particularly useful when using the
247
+ * MultiCurlRequestFactory.
248
+ */
249
+ public function setupCheckoutTracking(
250
+ $id,
251
+ $masterId = null,
252
+ $title = '',
253
+ $query = null,
254
+ $sid = null,
255
+ $cookieId = null,
256
+ $count = 1,
257
+ $price = null,
258
+ $userid = null
259
+ ) {
260
+ if (strlen($sid) == 0) $sid = session_id();
261
+ $params = array(
262
+ 'id' => $id,
263
+ 'masterId' => $masterId,
264
+ 'title' => $title,
265
+ 'sid' => $sid,
266
+ 'count' => $count,
267
+ 'event' => 'checkout'
268
+ );
269
+
270
+ if (strlen($price) > 0) $params['price'] = $price;
271
+ if (strlen($userid) > 0) $params['userId'] = $userid;
272
+ if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
273
+ if (strlen($query) > 0) $params['query'] = $query;
274
+ if (strlen($masterId) > 0) $params['masterId'] = $masterId;
275
+
276
+ $this->parameters->clear();
277
+ $this->parameters->setAll($params);
278
+ }
279
+
280
+ /**
281
+ * Track a click on a recommended product.
282
+ *
283
+ * @param string $id id of product
284
+ * @param int $mainId ID of the product for which the clicked-upon item was recommended
285
+ * @param string $masterid masterId of product if variant
286
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
287
+ * @param string $cookieId cookie id (optional)
288
+ * @param string $userid id of user (optional if modul personalisation is not used)
289
+ * @return boolean $success
290
+ */
291
+ public function trackRecommendationClick(
292
+ $id,
293
+ $mainId,
294
+ $masterId = null,
295
+ $sid = null,
296
+ $cookieId = null,
297
+ $userid = null
298
+ ) {
299
+ $this->setupRecommendationClickTracking($id, $mainId, $masterId, $sid, $cookieId, $userid);
300
+ return $this->applyTracking();
301
+ }
302
+
303
+ /**
304
+ * Use this method directly if you want to separate the setup from sending
305
+ * the request. This is particularly useful when using the
306
+ * MultiCurlRequestFactory.
307
+ */
308
+ public function setupRecommendationClickTracking(
309
+ $id,
310
+ $mainId,
311
+ $masterId = null,
312
+ $sid = null,
313
+ $cookieId = null,
314
+ $userid = null
315
+ ) {
316
+ if (strlen($sid) == 0) $sid = session_id();
317
+ $params = array(
318
+ 'id' => $id,
319
+ 'masterId' => $masterId,
320
+ 'sid' => $sid,
321
+ 'cookieId' => $cookieId,
322
+ 'mainId' => $mainId,
323
+ 'event' => 'recommendationClick'
324
+ );
325
+
326
+ if (strlen($userid) > 0) $params['userId'] = $userid;
327
+ if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
328
+ if (strlen($masterId) > 0) $params['masterId'] = $masterId;
329
+
330
+ $this->parameters->clear();
331
+ $this->parameters->setAll($params);
332
+ }
333
+
334
+ /**
335
+ * Track login of a user
336
+ *
337
+ * @param string $sid session id (if empty, then try to set using the function session_id() )
338
+ * @param string $cookieId cookie id (optional)
339
+ * @param string $userid id of user who logged in
340
+ * @return boolean $success
341
+ */
342
+ public function trackLogin(
343
+ $sid = null,
344
+ $cookieId = null,
345
+ $userid = null
346
+ ) {
347
+ $this->setupLoginTracking($sid, $cookieId, $userid);
348
+ return $this->applyTracking();
349
+ }
350
+
351
+ /**
352
+ * Use this method directly if you want to separate the setup from sending
353
+ * the request. This is particularly useful when using the
354
+ * MultiCurlRequestFactory.
355
+ */
356
+ public function setupLoginTracking(
357
+ $sid = null,
358
+ $cookieId = null,
359
+ $userid = null
360
+ ) {
361
+ if (strlen($sid) == 0) $sid = session_id();
362
+ $params = array(
363
+ 'sid' => $sid,
364
+ 'userId' => $userid,
365
+ 'event' => 'login'
366
+ );
367
+
368
+ if (strlen($cookieId) > 0) $params['cookieId'] = $cookieId;
369
+
370
+ $this->parameters->clear();
371
+ $this->parameters->setAll($params);
372
+ }
373
+
374
+ /**
375
+ * send tracking
376
+ *
377
+ * @return boolean $success
378
+ */
379
+ public function applyTracking() {
380
+ $success = trim($this->getResponseContent());
381
+ return $success == 'The event was successfully tracked' || $success == 'true' || $success == '1';
382
+ }
383
+ }
lib/FACTFinder/AdvisorAnswer.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents an answer to a question of an advisor campaign (see FACTFinder_AdvisorQuestion)
12
- * relevant for FF versions >= 6.7
13
- *
14
- * @author Martin Buettner <martin.buettner@omikron.net>
15
- * @version $Id: AdvisorAnswer.php 41893 2012-01-16 13:47:52Z mb $
16
- * @package FACTFinder\Common
17
- */
18
- class FACTFinder_AdvisorAnswer
19
- {
20
- private $text;
21
- private $params;
22
-
23
- private $subquestions = array();
24
-
25
- /**
26
- * @param string text
27
- * @param string params
28
- * @param array subquestions; array of FACTFinder_AdvisorQuestion objects
29
- */
30
- public function __construct($text = '', $params = '', $subquestions = array()) {
31
- $this->text = trim($text);
32
- $this->params = trim($params);
33
- $this->addSubquestions($subquestions);
34
- }
35
-
36
- /**
37
- * @return string text
38
- */
39
- public function getText() {
40
- return $this->text;
41
- }
42
-
43
- /**
44
- * @return string params
45
- */
46
- public function getParams() {
47
- return $this->params;
48
- }
49
-
50
- /**
51
- * add follow-up questions to this answer
52
- *
53
- * @param array of FACTFinder_AdvisorQuestion objects
54
- * @return void
55
- */
56
- public function addSubquestions(array $subquestions) {
57
- foreach ($subquestions AS $question) {
58
- $this->subquestions[] = $question;
59
- }
60
- }
61
-
62
- /**
63
- * true if follow-up questions exist
64
- *
65
- * @return boolean
66
- */
67
- public function hasSubquestions() {
68
- return sizeof($this->subquestions) > 0;
69
- }
70
-
71
- /**
72
- * @return array of FACTFinder_AdvisorQuestion objects
73
- */
74
- public function getSubquestions() {
75
- return $this->subquestions;
76
- }
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/AdvisorQuestion.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents a question of an advisor campaign
12
- * relevant for FF versions >= 6.7
13
- *
14
- * @author Martin Buettner <martin.buettner@omikron.net>
15
- * @version $Id: AdvisorQuestion.php 41893 2012-01-16 13:47:52Z mb $
16
- * @package FACTFinder\Common
17
- */
18
- class FACTFinder_AdvisorQuestion
19
- {
20
- private $text;
21
-
22
- private $answers = array();
23
-
24
- /**
25
- * @param string question text
26
- * @param array answers; array of FACTFinder_AdvisorAnswer objects
27
- */
28
- public function __construct($text = '', $answers = array()) {
29
- $this->text = trim($text);
30
- $this->addAnswers($answers);
31
- }
32
-
33
- /**
34
- * @return string text
35
- */
36
- public function getText() {
37
- return $this->text;
38
- }
39
-
40
- /**
41
- * add answers to this question
42
- *
43
- * @param array of FACTFinder_AdvisorAnswer objects
44
- * @return void
45
- */
46
- public function addAnswers(array $answers) {
47
- foreach ($answers AS $answer) {
48
- $this->answers[] = $answer;
49
- }
50
- }
51
-
52
- /**
53
- * true if answers exist
54
- *
55
- * @return boolean
56
- */
57
- public function hasAnswers() {
58
- return sizeof($this->answers) > 0;
59
- }
60
-
61
- /**
62
- * @return array of FACTFinder_AdvisorAnswer objects
63
- */
64
- public function getAnswers() {
65
- return $this->answers;
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Asn.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents a group in the ASN which contains several filters. By iterating over an ASN object, you will
12
- * get FACTFinder_AsnGroup objects in the loop.
13
- *
14
- * @author Rudolf Batt <rb@omikron.net>
15
- * @version $Id: Asn.php 25893 2010-06-29 08:19:43Z rb $
16
- * @package FACTFinder\Common
17
- */
18
- class FACTFinder_Asn extends ArrayIterator
19
- {
20
- /**
21
- * decorates the FACTFinder_AsnGroup::hasPreviewImages() method for each group in the asn. so if one group has
22
- * preview images, this method returns true
23
- *
24
- * @return boolean
25
- */
26
- public function hasPreviewImages()
27
- {
28
- $hasPreviewImages = false;
29
- foreach ($this AS $group) {
30
- if ($group->hasPreviewImages()) {
31
- $hasPreviewImages = true;
32
- break;
33
- }
34
- }
35
- return $hasPreviewImages;
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/AsnFilterItem.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents an filterable item from the after search navigation
12
- *
13
- * @author Rudolf Batt <rb@omikron.net>
14
- * @version $Id: AsnFilterItem.php 25893 2010-06-29 08:19:43Z rb $
15
- * @package FACTFinder\Common
16
- */
17
- class FACTFinder_AsnFilterItem extends FACTFinder_Item
18
- {
19
- private $matchCount;
20
- private $clusterLevel;
21
- private $previewImage = null;
22
- private $field;
23
-
24
- public function __construct($value, $url, $isSelected = false, $matchCount = 0, $clusterLevel = 0, $previewImage = null, $field = ''){
25
- parent::__construct($value, $url, $isSelected);
26
- $this->matchCount = intval($matchCount);
27
- $this->clusterLevel = intval($clusterLevel);
28
- $this->previewImage = strval($previewImage);
29
- $this->field = strval($field);
30
- }
31
-
32
- public function getType() {
33
- return 'item';
34
- }
35
-
36
- /**
37
- * @return String
38
- */
39
- public function getField() {
40
- return $this->field;
41
- }
42
-
43
- /**
44
- * @return int
45
- */
46
- public function getMatchCount() {
47
- return $this->matchCount;
48
- }
49
-
50
- /**
51
- * @return int
52
- */
53
- public function getClusterLevel() {
54
- return $this->clusterLevel;
55
- }
56
-
57
- /**
58
- * return url of a preview image or null if there is no set
59
- *
60
- * @return string image url or null if none exists
61
- */
62
- public function getPreviewImage() {
63
- return $this->previewImage;
64
- }
65
-
66
- /**
67
- * @return boolean
68
- */
69
- public function hasPreviewImage() {
70
- return strlen($this->previewImage) > 0;
71
- }
72
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/AsnGroup.php DELETED
@@ -1,177 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents a group in the ASN which contains several filters. By iterating over an AsnGroup object, you will
12
- * get AsnFilterItem objects in the loop.
13
- *
14
- * @author Rudolf Batt <rb@omikron.net>
15
- * @version $Id: AsnGroup.php 25893 2010-06-29 08:19:43Z rb $
16
- * @category Collection
17
- * @package FACTFinder\Common
18
- */
19
-
20
- /* enum workaround */
21
- abstract class FACTFinder_FilterStyle
22
- {
23
- const Regular = 0;
24
- const Slider = 1;
25
- const Color = 2;
26
- const Tree = 3;
27
- const MultiSelect = 4;
28
- }
29
-
30
- class FACTFinder_AsnGroup extends ArrayIterator
31
- {
32
- private $name;
33
- private $detailedLinkCount;
34
- private $unit;
35
- private $hasPreviewImages = false;
36
- private $hasSelectedItems = false;
37
- private $style = FACTFinder_FilterStyle::Regular;
38
-
39
- /**
40
- * constructor
41
- *
42
- * @param array asn filters to add to this group (default: empty array)
43
- * @param string name of the group (default: empty string)
44
- * @param int number of detail links to show (default: 0)
45
- * @param string untit character of the group (default: empty string)
46
- * @param string style; possible values: DEFAULT|SLIDER|COLOR|TREE|MULTISELECT (default: DEFAULT)
47
- */
48
- public function __construct(array $asnFilters = array(), $name = '', $detailedLinkCount = 0, $unit = '', $style = 'DEFAULT') {
49
- $this->name = strval($name);
50
- $this->detailedLinkCount = intval($detailedLinkCount);
51
- $this->unit = strval($unit);
52
- switch($style)
53
- {
54
- case 'SLIDER':
55
- $this->style = FACTFinder_FilterStyle::Slider;
56
- break;
57
- case 'COLOR':
58
- $this->style = FACTFinder_FilterStyle::Color;
59
- break;
60
- case 'TREE':
61
- $this->style = FACTFinder_FilterStyle::Tree;
62
- break;
63
- case 'MULTISELECT':
64
- $this->style = FACTFinder_FilterStyle::MultiSelect;
65
- break;
66
- default:
67
- $this->style = FACTFinder_FilterStyle::Regular;
68
- break;
69
- }
70
-
71
- parent::__construct();
72
- $this->addFilters($asnFilters);
73
- }
74
-
75
- /**
76
- * @return boolean
77
- */
78
- public function isDefaultStyle() {
79
- return $this->style === FACTFinder_FilterStyle::Regular;
80
- }
81
-
82
- /**
83
- * return true if group filtering should be done in slider style
84
- *
85
- * @return boolean
86
- */
87
- public function isSliderStyle() {
88
- return $this->style === FACTFinder_FilterStyle::Slider;
89
- }
90
-
91
- /**
92
- * @return boolean
93
- */
94
- public function isColorStyle() {
95
- return $this->style === FACTFinder_FilterStyle::Color;
96
- }
97
-
98
- /**
99
- * @return boolean
100
- */
101
- public function isTreeStyle() {
102
- return $this->style === FACTFinder_FilterStyle::Tree;
103
- }
104
-
105
- /**
106
- * @return boolean
107
- */
108
- public function isMultiSelectStyle() {
109
- return $this->style === FACTFinder_FilterStyle::MultiSelect;
110
- }
111
-
112
- /**
113
- * return boolean true if one or more items has a preview image
114
- */
115
- public function hasPreviewImages()
116
- {
117
- return $this->hasPreviewImages;
118
- }
119
-
120
- /**
121
- * return boolean true if one or more items are selected
122
- */
123
- public function hasSelectedItems()
124
- {
125
- return $this->hasSelectedItems;
126
- }
127
-
128
- /**
129
- * add every filter from the given array to this group
130
- *
131
- * @param array of filter objects
132
- * @return void
133
- */
134
- public function addFilters(array $filters)
135
- {
136
- foreach($filters AS $filter) {
137
- $this->addFilter($filter);
138
- }
139
- }
140
-
141
- /**
142
- * @param filter object
143
- * @return void
144
- */
145
- public function addFilter($filter)
146
- {
147
- if ($filter instanceof FACTFinder_AsnFilterItem) {
148
- if ($filter->hasPreviewImage()) {
149
- $this->hasPreviewImages = true;
150
- } else if ($filter->isSelected()) {
151
- $this->hasSelectedItems = true;
152
- }
153
- }
154
- parent::append($filter);
155
- }
156
-
157
- /**
158
- * @return string name
159
- */
160
- public function getName() {
161
- return $this->name;
162
- }
163
-
164
- /**
165
- * @return string unit
166
- */
167
- public function getUnit() {
168
- return $this->unit;
169
- }
170
-
171
- /**
172
- * @return int
173
- */
174
- public function getDetailedLinkCount() {
175
- return $this->detailedLinkCount;
176
- }
177
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/AsnSliderFilter.php DELETED
@@ -1,139 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents an asn filter slider item
12
- *
13
- * @author Rudolf Batt <rb@omikron.net>
14
- * @version $Id: AsnSliderFilter.php 25893 2010-06-29 08:19:43Z rb $
15
- * @package FACTFinder\Common
16
- */
17
- class FACTFinder_AsnSliderFilter
18
- {
19
- private $absoluteMin;
20
- private $absoluteMax;
21
- private $selectedMin;
22
- private $selectedMax;
23
- private $baseUrl;
24
- private $field;
25
-
26
- /**
27
- * @param string base url - it should be possible to simply append the selected min and max value
28
- * @param float absolute min (default: 0.0)
29
- * @param float absolute max (default: 0.0)
30
- * @param float selected min (default: 0.0)
31
- * @param float selected max (default: 0.0)
32
- */
33
- public function __construct($baseUrl, $absoluteMin = 0, $absoluteMax = 0, $selectedMin = 0, $selectedMax = 0, $field = '') {
34
- $this->baseUrl = $baseUrl;
35
- $this->setAbsoluteRange($absoluteMin, $absoluteMax);
36
- $this->setSelectedRange($selectedMin, $selectedMax);
37
- $this->field = strval($field);
38
- }
39
-
40
- public function getType() {
41
- return 'slider';
42
- }
43
-
44
- /**
45
- * @param float absolute min
46
- * @param float absolute max
47
- */
48
- private function setAbsoluteRange($min, $max) {
49
- $this->absoluteMin = floatval($min);
50
- $this->absoluteMax = floatval($max);
51
- }
52
-
53
- /**
54
- * @param float selected min
55
- * @param float selected max
56
- */
57
- public function setSelectedRange($min, $max) {
58
- $this->selectedMin = floatval($min);
59
- $this->selectedMax = floatval($max);
60
- }
61
-
62
- /**
63
- * return float
64
- */
65
- public function getAbsoluteMin() {
66
- return $this->absoluteMin;
67
- }
68
-
69
- /**
70
- * return float
71
- */
72
- public function getAbsoluteMax() {
73
- return $this->absoluteMax;
74
- }
75
-
76
- /**
77
- * return float
78
- */
79
- public function getSelectedMin() {
80
- return $this->selectedMin;
81
- }
82
-
83
- /**
84
- * return float
85
- */
86
- public function getSelectedMax() {
87
- return $this->selectedMax;
88
- }
89
-
90
- /**
91
- * @return string url for the current selected range
92
- */
93
- public function getUrl() {
94
- return $this->baseUrl . $this->selectedMin . ' - ' . $this->selectedMax;
95
- }
96
-
97
- /**
98
- * @return string base url
99
- */
100
- public function getBaseUrl() {
101
- return $this->baseUrl;
102
- }
103
-
104
- /**
105
- * Allows to overwrite the base url.
106
- * @param $url string new url
107
- */
108
- public function setBaseUrl($url) {
109
- $this->baseUrl = $url;
110
- }
111
-
112
- /**
113
- * returns true if the selected range is not the same as the absolute range
114
- *
115
- * @return boolean true if selected
116
- */
117
- public function isSelected() {
118
- return $this->selectedMin != $this->absoluteMin || $this->selectedMax != $this->absoluteMax;
119
- }
120
-
121
- /**
122
- * returns the associated field name to this filter
123
- *
124
- * @return string field-name
125
- */
126
- public function getField() {
127
- return $this->field;
128
- }
129
-
130
- /**
131
- * returns the absolute values as parameters and the select parameter-key, so the selected values must be
132
- * appended to set the selection.
133
- *
134
- * @return string parameters for this filter
135
- */
136
- public function getValue() {
137
- return 'filter'.$this->getField().'Absolute='.$this->getAbsoluteMin().' - '.$this->getAbsoluteMax().'&filter'.$this->getField().'=';
138
- }
139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/BreadCrumbItem.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * breadcrumb for the breadcrumb navigation
12
- *
13
- * @author Rudolf Batt <rb@omikron.net>
14
- * @version $Id: BreadCrumbItem.php 25893 2010-06-29 08:19:43Z rb $
15
- * @package FACTFinder\Common
16
- */
17
- class FACTFinder_BreadCrumbItem extends FACTFinder_Item
18
- {
19
- const SEARCH_TYPE = 'search';
20
- const FILTER_TYPE = 'filter';
21
-
22
- private $type;
23
- private $fieldName;
24
- private $fieldUnit;
25
-
26
- /**
27
- * @param string value
28
- * @param string url
29
- * @param boolean true if this breadcrumb represents the current state of the result
30
- * @param string type should be "search" or "filter", otherwise the "is..." methods will not work (default: 'filter')
31
- * @param string filtername
32
- * @param string filter value
33
- */
34
- public function __construct($value, $url, $isSelected = false, $type = 'filter', $fieldName = '', $fieldUnit = '')
35
- {
36
- parent::__construct($value, $url, $isSelected);
37
- $this->type = strval($type);
38
- if ($this->isFilter()) {
39
- $this->fieldName = strval($fieldName);
40
- $this->fieldUnit = strval($fieldUnit);
41
- }
42
- }
43
-
44
- /**
45
- * @return boolean
46
- */
47
- public function isFilter()
48
- {
49
- return $this->type == self::FILTER_TYPE;
50
- }
51
-
52
- /**
53
- * @return boolean
54
- */
55
- public function isSearch()
56
- {
57
- return $this->type == self::SEARCH_TYPE;
58
- }
59
-
60
- /**
61
- * @return string
62
- */
63
- public function getFieldName()
64
- {
65
- return $this->fieldName;
66
- }
67
-
68
- /**
69
- * @return string
70
- */
71
- public function getFieldUnit()
72
- {
73
- return $this->fieldUnit;
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Campaign.php DELETED
@@ -1,206 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents a factfinder campaign
12
- *
13
- * @author Rudolf Batt <rb@omikron.net>
14
- * @version $Id: Campaign.php 25985 2010-06-30 15:31:53Z rb $
15
- * @package FACTFinder\Common
16
- */
17
- class FACTFinder_Campaign
18
- {
19
- private $name;
20
- private $category;
21
-
22
- private $redirectUrl = null;
23
- private $pushedProducts = array();
24
- private $feedback = array();
25
- private $activeQuestions = array();
26
- private $advisorTree = array();
27
-
28
- /**
29
- * @param string name
30
- * @param string category
31
- * @param string redirectUrl (default: empty string)
32
- * @param array pushedProducts; array of records
33
- * @param array feedback; array of strings with labels as keys
34
- * @param array activeQuestions; array of FACTFinder_AdvisorQuestion objects
35
- */
36
- public function __construct($name = '', $category = '', $redirectUrl = '', array $pushedProducts = array(), $feedback = array(), $activeQuestions = array(), $advisorTree = array()) {
37
- $this->name = trim($name);
38
- $this->category = trim($category);
39
- $this->redirectUrl = trim($redirectUrl);
40
- $this->addPushedProducts($pushedProducts);
41
- $this->addFeedback($feedback);
42
- $this->addActiveQuestions($activeQuestions);
43
- $this->addToAdvisorTree($advisorTree);
44
- }
45
-
46
- /**
47
- * @return string name
48
- */
49
- public function getName() {
50
- return $this->name;
51
- }
52
-
53
- /**
54
- * @return string url
55
- */
56
- public function getCategory(){
57
- return $this->category;
58
- }
59
-
60
- /**
61
- * true if a redirect link was set
62
- *
63
- * @return boolean
64
- */
65
- public function hasRedirect()
66
- {
67
- return !empty($this->redirectUrl);
68
- }
69
-
70
- /**
71
- * @return string url
72
- */
73
- public function getRedirectUrl(){
74
- return $this->redirectUrl;
75
- }
76
-
77
- /**
78
- * add products to this campaign
79
- *
80
- * @param array of FACTFinder_Record objects
81
- * @return void
82
- */
83
- public function addPushedProducts(array $pushedProducts) {
84
- foreach ($pushedProducts AS $product) {
85
- $this->pushedProducts[] = $product;
86
- }
87
- }
88
-
89
- /**
90
- * true if pushed products exist
91
- *
92
- * @return boolean
93
- */
94
- public function hasPushedProducts() {
95
- return sizeof($this->pushedProducts) > 0;
96
- }
97
-
98
- /**
99
- * @return array of FACTFinder_Record objects
100
- */
101
- public function getPushedProducts() {
102
- return $this->pushedProducts;
103
- }
104
-
105
- /**
106
- * set the feedback strings. if a feedback with the same key (label) exist, it will be overwritten
107
- *
108
- * @param array of string
109
- * @return void
110
- */
111
- public function addFeedback(array $feedback) {
112
- foreach($feedback AS $label => $text) {
113
- $this->feedback[$label] = trim($text);
114
- }
115
- }
116
-
117
- /**
118
- * returns true if feedback exists. if argument is specified, this methods checks, whether there is any
119
- * feedback text available. if a label is given, then this method only returns true, if there is a feedback text
120
- * for this label
121
- *
122
- * @param string label of feedback (default: null)
123
- * @return boolean
124
- */
125
- public function hasFeedback($label = null) {
126
- if ($label != null) {
127
- $hasFeedback = isset($this->feedback[$label]) && $this->feedback[$label] != '';
128
- } else {
129
- $hasFeedback = sizeof($this->feedback) > 0 && implode('', $this->feedback) != '';
130
- }
131
- return $hasFeedback;
132
- }
133
-
134
- /**
135
- * when label is specified, only the desired feedback text will be returned or an empty string, if this text does not exist.
136
- * if no label is set, the complete feedback array will be returned
137
- *
138
- * @param string $label
139
- * @return array|string
140
- */
141
- public function getFeedback($label = null) {
142
- if ($label === null) {
143
- return $this->feedback;
144
- } else if (isset($this->feedback[$label])) {
145
- return $this->feedback[$label];
146
- } else {
147
- return '';
148
- }
149
- }
150
-
151
- /**
152
- * add active questions to this campaign
153
- *
154
- * @param array of FACTFinder_AdvisorQuestion objects
155
- * @return void
156
- */
157
- public function addActiveQuestions(array $activeQuestions) {
158
- foreach ($activeQuestions AS $question) {
159
- $this->activeQuestions[] = $question;
160
- }
161
- }
162
-
163
- /**
164
- * true if advisor questions exist
165
- *
166
- * @return boolean
167
- */
168
- public function hasActiveQuestions() {
169
- return sizeof($this->activeQuestions) > 0;
170
- }
171
-
172
- /**
173
- * @return array of FACTFinder_AdvisorQuestion objects
174
- */
175
- public function getActiveQuestions() {
176
- return $this->activeQuestions;
177
- }
178
-
179
- /**
180
- * add questions to the advisor tree (top level) of this campaign
181
- *
182
- * @param array of FACTFinder_AdvisorQuestion objects
183
- * @return void
184
- */
185
- public function addToAdvisorTree(array $advisorTree) {
186
- foreach ($advisorTree AS $question) {
187
- $this->advisorTree[] = $question;
188
- }
189
- }
190
-
191
- /**
192
- * true if advisor tree exists
193
- *
194
- * @return boolean
195
- */
196
- public function hasAdvisorTree() {
197
- return sizeof($this->advisorTree) > 0;
198
- }
199
-
200
- /**
201
- * @return array of FACTFinder_AdvisorQuestion objects
202
- */
203
- public function getAdvisorTree() {
204
- return $this->advisorTree;
205
- }
206
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/CampaignIterator.php DELETED
@@ -1,190 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * represents the whole collection of campaigns. decorates some campaign functions to execute on every campaign.
12
- * By iterating over an CampaignIterator you get FACTFinder_Campaign objects in the loop.
13
- *
14
- * @author Rudolf Batt <rb@omikron.net>
15
- * @version $Id: CampaignIterator.php 25985 2010-06-30 15:31:53Z rb $
16
- * @package FACTFinder\Common
17
- */
18
- class FACTFinder_CampaignIterator extends ArrayIterator
19
- {
20
- /**
21
- * true if a redirect link exists at one of all campaigns
22
- *
23
- * @see FACTFinder_Campaign::hasRedirect()
24
- * @return boolean
25
- */
26
- public function hasRedirect()
27
- {
28
- $hasRedirect = false;
29
- foreach ($this AS $campaign) {
30
- if ($campaign->hasRedirect()) {
31
- $hasRedirect = true;
32
- break;
33
- }
34
- }
35
- return $hasRedirect;
36
- }
37
-
38
- /**
39
- * return the first redirect of all campaigns or null if non exists
40
- *
41
- * @see FACTFinder_Campaign::getRedirectUrl()
42
- * @return string url
43
- */
44
- public function getRedirectUrl(){
45
- $redirectUrl = null;
46
- foreach ($this AS $campaign) {
47
- if ($campaign->hasRedirect()) {
48
- $redirectUrl = $campaign->getRedirectUrl();
49
- break;
50
- }
51
- }
52
- return $redirectUrl;
53
- }
54
-
55
- /**
56
- * true if pushed products exist in of all campaigns
57
- *
58
- * @see FACTFinder_Campaign::hasPushedProducts()
59
- * @return boolean
60
- */
61
- public function hasPushedProducts() {
62
- $hasPushedProducts = false;
63
- foreach ($this AS $campaign) {
64
- if ($campaign->hasPushedProducts()) {
65
- $hasPushedProducts = true;
66
- break;
67
- }
68
- }
69
- return $hasPushedProducts;
70
- }
71
-
72
- /**
73
- * decorates FACTFinder_Campaign::getPushedProducts() for all campaigns
74
- *
75
- * @see FACTFinder_Campaign::getPushedProducts()
76
- * @return array of records
77
- */
78
- public function getPushedProducts() {
79
- $pushedProducts = array();
80
- foreach ($this AS $campaign) {
81
- if ($campaign->hasPushedProducts()) {
82
- $pushedProducts = array_merge($pushedProducts, $campaign->getPushedProducts());
83
- }
84
- }
85
- return $pushedProducts;
86
- }
87
-
88
- /**
89
- * decorates FACTFinder_Campaign::hasFeedback() for each campaign. return true, if one of all campaigns has feedback
90
- * text snippets
91
- *
92
- * @see FACTFinder_Campaign::hasFeedback()
93
- * @return boolean
94
- */
95
- public function hasFeedback($nr = null) {
96
- $hasFeedback = false;
97
- foreach ($this AS $campaign) {
98
- if ($campaign->hasFeedback($nr)) {
99
- $hasFeedback = true;
100
- break;
101
- }
102
- }
103
- return $hasFeedback;
104
- }
105
-
106
- /**
107
- * decorates FACTFinder_Campaign::getFeedback() for each campaign. returnes a string of each feedback from all
108
- * campaigns, glued together with PHP_EOL
109
- *
110
- * @see FACTFinder_Campaign::getFeedback()
111
- * @param int $nr of feedback text
112
- * @return string
113
- */
114
- public function getFeedback($nr) {
115
- $feedback = '';
116
- foreach ($this AS $campaign) {
117
- if ($campaign->hasFeedback()) {
118
- $feedback .= $campaign->getFeedback($nr).PHP_EOL;
119
- }
120
- }
121
- return $feedback;
122
- }
123
-
124
- /**
125
- * true if active advisor questions exist in any campaign
126
- *
127
- * @see FACTFinder_Campaign::hasActiveQuestions()
128
- * @return boolean
129
- */
130
- public function hasActiveQuestions() {
131
- $hasActiveQuestions = false;
132
- foreach ($this AS $campaign) {
133
- if ($campaign->hasActiveQuestions()) {
134
- $hasActiveQuestions = true;
135
- break;
136
- }
137
- }
138
- return $hasActiveQuestions;
139
- }
140
-
141
- /**
142
- * decorates FACTFinder_Campaign::getActiveQuestions() for all campaigns
143
- *
144
- * @see FACTFinder_Campaign::getActiveQuestions()
145
- * @return array of records
146
- */
147
- public function getActiveQuestions() {
148
- $activeQuestions = array();
149
- foreach ($this AS $campaign) {
150
- if ($campaign->hasActiveQuestions()) {
151
- $activeQuestions = array_merge($activeQuestions, $campaign->getActiveQuestions());
152
- }
153
- }
154
- return $activeQuestions;
155
- }
156
-
157
-
158
- /**
159
- * true if an advisor tree exists in any campaign
160
- *
161
- * @see FACTFinder_Campaign::hasActiveQuestions()
162
- * @return boolean
163
- */
164
- public function hasAdvisorTree() {
165
- $hasAdvisorTree = false;
166
- foreach ($this AS $campaign) {
167
- if ($campaign->hasAdvisorTree()) {
168
- $hasAdvisorTree = true;
169
- break;
170
- }
171
- }
172
- return $hasAdvisorTree;
173
- }
174
-
175
- /**
176
- * decorates FACTFinder_Campaign::getAdvisorTree() for all campaigns
177
- *
178
- * @see FACTFinder_Campaign::getAdvisorTree()
179
- * @return array of records
180
- */
181
- public function getAdvisorTree() {
182
- $advisorTree = array();
183
- foreach ($this AS $campaign) {
184
- if ($campaign->hasAdvisorTree()) {
185
- $advisorTree = array_merge($advisorTree, $campaign->getAdvisorTree());
186
- }
187
- }
188
- return $advisorTree;
189
- }
190
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Configuration.php DELETED
@@ -1,448 +0,0 @@
1
- <?php
2
- /**
3
- * FACT-Finder PHP Framework
4
- *
5
- * @category Library
6
- * @package FACTFinder\Common
7
- * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
8
- */
9
-
10
- /**
11
- * this class implements the FACTFinder configuration interface and uses the Zend_Config class. so it's like a decorator
12
- * for the Zend_Config
13
- *
14
- * @package FACTFinder\Common
15
- */
16
- class FACTFinder_Configuration implements FACTFinder_Abstract_Configuration
17
- {
18
- const HTTP_AUTH = 'http';
19
- const SIMPLE_AUTH = 'simple';
20
- const ADVANCED_AUTH = 'advanced';
21
-
22
- protected $zendConfig;
23
- private $authType;
24
- private $pageMappings;
25
- private $serverMappings;
26
- private $pageIgnores;
27
- private $serverIgnores;
28
- private $requiredPageParams;
29
- private $requiredServerParams;
30
-
31
- public function __construct(Zend_Config $config)
32
- {
33
- $this->zendConfig = $config;
34
- }
35
-
36
- /**
37
- * @return string
38
- */
39
- public function getVersion() {
40
- return $this->zendConfig->version;
41
- }
42
-
43
- /**
44
- * @return boolean
45
- * @deprecated
46
- */
47
- public function isDebugEnabled() {
48
- return $this->zendConfig->debug == 'true';
49
- }
50
-
51
- /**
52
- * @param string name
53
- * @return string value
54
- */
55
- public function getCustomValue($name) {
56
- return $this->zendConfig->$name;
57
- }
58
-
59
- /**
60
- * @deprecated because of wrong spelling. use "getRequestProtocol()" instead
61
- * @return string
62
- */
63
- public function getRequestProtokoll() {
64
- return $this->zendConfig->search->protokoll;
65
- }
66
-
67
- /**
68
- * @return string
69
- */
70
- public function getRequestProtocol() {
71
- $protocol = $this->zendConfig->search->protocol;
72
-
73
- // legacy code for older configurations
74
- if (empty($protocol)) {
75
- $protocol = $this->getRequestProtokoll();
76
- }
77
- return $protocol;
78
- }
79
-
80
- /**
81
- * @return string
82
- */
83
- public function getServerAddress() {
84
- return $this->zendConfig->search->address;
85
- }
86
-
87
- /**
88
- * @return int
89
- */
90
- public function getServerPort() {
91
- return $this->zendConfig->search->port;
92
- }
93
-
94
- /**
95
- * @return string
96
- */
97
- public function getContext() {
98
- return $this->zendConfig->search->context;
99
- }
100
-
101
- /**
102
- * @return string
103
- */
104
- public function getChannel() {
105
- return $this->zendConfig->search->channel;
106
- }
107
-
108
- /**
109
- * @return string
110
- */
111
- public function getLanguage() {
112
- return $this->zendConfig->search->language;
113
- }
114
-
115
- /**
116
- * @return string
117
- */
118
- public function getAuthUser() {
119
- return $this->zendConfig->search->auth->user;
120
- }
121
-
122
- /**
123
- * @return string
124
- */
125
- public function getAuthPasswort() {
126
- return $this->zendConfig->search->auth->password;
127
- }
128
-
129
- /**
130
- * @return boolean
131
- */
132
- public function isHttpAuthenticationType() {
133
- return $this->getAuthType() == self::HTTP_AUTH;
134
- }
135
-
136
- /**
137
- * @return boolean
138
- */
139
- public function isSimpleAuthenticationType() {
140
- return $this->getAuthType() == self::SIMPLE_AUTH;
141
- }
142
-
143
- /**
144
- * @return boolean
145
- */
146
- public function isAdvancedAuthenticationType() {
147
- return $this->getAuthType() == self::ADVANCED_AUTH;
148
- }
149
-
150
- private function getAuthType() {
151
- if ($this->authType == null) {
152
- $this->authType = $this->zendConfig->search->auth->type;
153
- if ( $this->authType != self::HTTP_AUTH
154
- && $this->authType != self::SIMPLE_AUTH
155
- && $this->authType != self::ADVANCED_AUTH ) {
156
- $this->authType = self::HTTP_AUTH;
157
- }
158
- }
159
- return $this->authType;
160
- }
161
-
162
- /**
163
- * @return string
164
- */
165
- public function getAdvancedAuthPrefix() {
166
- return $this->zendConfig->search->auth->advancedPrefix;
167
- }
168
-
169
- /**
170
- * @return string
171
- */
172
- public function getAdvancedAuthPostfix(){
173
- return $this->zendConfig->search->auth->advancedPostfix;
174
- }
175
-
176
- /**
177
- * get mappings for the webpage
178
- *
179
- * @return array
180
- */
181
- public function getPageMappings() {
182
- if ($this->pageMappings == null) {
183
- $this->pageMappings = array();
184
- if ($this->zendConfig->params->client->mapping != null) {
185
-
186
- // get mapping config as iterable variable
187
- if ($this->zendConfig->params->client->mapping->from == null) {
188
- $mapping = $this->zendConfig->params->client->mapping;
189
- } else {
190
- $mapping = array($this->zendConfig->params->client->mapping);
191
- }
192
-
193
- //load mappings
194
- foreach($mapping AS $rule) {
195
- $this->pageMappings[$rule->from] = $rule->to;
196
- }
197
- }
198
- }
199
- return $this->pageMappings;
200
- }
201
-
202
- /**
203
- * get mappings for the server request
204
- *
205
- * @return array
206
- */
207
- public function getServerMappings() {
208
- if ($this->serverMappings == null) {
209
- $this->serverMappings = array();
210
- if ($this->zendConfig->params->server->mapping != null) {
211
-
212
- // get mapping config as iterable variable
213
- if ($this->zendConfig->params->server->mapping->from == null) {
214
- $mapping = $this->zendConfig->params->server->mapping;
215
- } else {
216
- $mapping = array($this->zendConfig->params->server->mapping);
217
- }
218
-
219
- //load mappings
220
- foreach($mapping AS $rule) {
221
- $this->serverMappings[$rule->from] = $rule->to;
222
- }
223
- }
224
- }
225
- return $this->serverMappings;
226
- }
227
-
228
- /**
229
- * get ignored parameters for the webpage request
230
- *
231
- * @return array with string as key and boolean true as value for each of them
232
- */
233
- public function getIgnoredPageParams() {
234
- if ($this->pageIgnores == null) {
235
- $this->pageIgnores = array();
236
- if (isset($this->zendConfig->params->client->ignore)) {
237
-
238
- // get ignore rules as iterable variable
239
- if($this->zendConfig->params->client->ignore->name == null) {
240
- $ignoreRules = $this->zendConfig->params->client->ignore ;
241
- } else {
242
- $ignoreRules = array($this->zendConfig->params->client->ignore );
243
- }
244
-
245
- // load ignore rules
246
- foreach($ignoreRules AS $i) {
247
- $this->pageIgnores[$i->name] = true;
248
- }
249
- }
250
-
251
- $pageMappings = $this->getPageMappings();
252
- foreach ($pageMappings AS $from => $to) {
253
- $this->pageIgnores[$from] = true;
254
- }
255
- }
256
- return $this->pageIgnores;
257
- }
258
-
259
- /**
260
- * get ignored parameters for the server request
261
- *
262
- * @return array with string as key and boolean true as value for each of them
263
- */
264
- public function getIgnoredServerParams() {
265
- if ($this->serverIgnores == null) {
266
- $this->serverIgnores = array();
267
- if (isset($this->zendConfig->params->server->ignore)) {
268
-
269
- // get ignore rules as iterable variable
270
- if($this->zendConfig->params->server->ignore->name == null) {
271
- $ignoreRules = $this->zendConfig->params->server->ignore ;
272
- } else {
273
- $ignoreRules = array($this->zendConfig->params->server->ignore );
274
- }
275
-
276
- // load ignore rules
277
- foreach($ignoreRules AS $i) {
278
- $this->serverIgnores[$i->name] = true;
279
- }
280
- }
281
-
282
- $serverMappings = $this->getServerMappings();
283
- foreach ($serverMappings AS $from => $to) {
284
- $this->serverIgnores[$from] = true;
285
- }
286
- }
287
- return $this->serverIgnores;
288
- }
289
-
290
- /**
291
- * get required parameters for the webpage request
292
- *
293
- * @return array string to string map (param-name as array-key; default value as array-value)
294
- */
295
- public function getRequiredPageParams(){
296
- if ($this->requiredPageParams == null) {
297
- $this->requiredPageParams = array();
298
- if ($this->zendConfig->params->client->required != null) {
299
-
300
- // get required params config as iterable variable
301
- if ($this->zendConfig->params->client->required->name == null) {
302
- $requiredParams = $this->zendConfig->params->client->required;
303
- } else {
304
- $requiredParams = array($this->zendConfig->params->client->required);
305
- }
306
-
307
- //load mappings
308
- foreach($requiredParams AS $param) {
309
- $this->requiredPageParams[$param->name] = $param->default;
310
- }
311
- }
312
- }
313
- return $this->requiredPageParams;
314
- }
315
-
316
- /**
317
- * get required paramters for the server request
318
- *
319
- * @return array string to string map (param-name as array-key; default value as array-value)
320
- */
321
- function getRequiredServerParams(){
322
- if ($this->requiredServerParams == null) {
323
- $this->requiredServerParams = array();
324
- if ($this->zendConfig->params->server->required != null) {
325
-
326
- // get required params config as iterable variable
327
- if ($this->zendConfig->params->server->required->name == null) {
328
- $requiredParams = $this->zendConfig->params->server->required;
329
- } else {
330
- $requiredParams = array($this->zendConfig->params->server->required);
331
- }
332
-
333
- //load mappings
334
- foreach($requiredParams AS $param) {
335
- $this->requiredServerParams[$param->name] = $param->default;
336
- }
337
- }
338
- }
339
- return $this->requiredServerParams;
340
- }
341
-
342
- /**
343
- * get default connect timeout for all adapters
344
- *
345
- * @return string
346
- **/
347
-
348
- function getDefaultConnectTimeout() {
349
- return $this->zendConfig->search->timeouts->defaultConnectTimeout;
350
- }
351
-
352
- /**
353
- * get default timeout for all adapters
354
- *
355
- * @return string
356
- **/
357
-
358
- function getDefaultTimeout() {
359
- return $this->zendConfig->search->timeouts->defaultTimeout;
360
- }
361
-
362
- /**
363
- * get connect timeout for suggest adapter
364
- *
365
- * @return string
366
- **/
367
-
368
- function getSuggestConnectTimeout() {
369
- return $this->zendConfig->search->timeouts->suggestConnectTimeout;
370
- }
371
-
372
- /**
373
- * get timeout for suggest adapter
374
- *
375
- * @return string
376
- **/
377
-
378
- function getSuggestTimeout() {
379
- return $this->zendConfig->search->timeouts->suggestTimeout;
380
- }
381
-
382
- /**
383
- * get connect timeout for scic adapter
384
- *
385
- * @return string
386
- **/
387
-
388
- function getScicConnectTimeout() {
389
- return $this->zendConfig->search->timeouts->scicConnectTimeout;
390
- }
391
-
392
- /**
393
- * get timeout for scic adapter
394
- *
395
- * @return string
396
- **/
397
-
398
- function getScicTimeout() {
399
- return $this->zendConfig->search->timeouts->scicTimeout;
400
- }
401
-
402
- /**
403
- * get connect timeout for import adapter
404
- *
405
- * @return string
406
- **/
407
-
408
- function getImportConnectTimeout() {
409
- return $this->zendConfig->search->timeouts->importConnectTimeout;
410
- }
411
-
412
- /**
413
- * get timeout for import adapter
414
- *
415
- * @return string
416
- **/
417
-
418
- function getImportTimeout() {
419
- return $this->zendConfig->search->timeouts->importTimeout;
420
- }
421
-
422
- /**
423
- * get encoding for the webpage
424
- *
425
- * @return string
426
- */
427
- function getPageContentEncoding() {
428
- return $this->zendConfig->encoding->pageContent;
429
- }
430
-
431
- /**
432
- * get encoding for the webpage url
433
- *
434
- * @return string
435
- */
436
- function getPageUrlEncoding() {
437
- return $this->zendConfig->encoding->pageURI;
438
- }
439
-
440
- /**
441
- * get server url encoding
442
- *
443
- * @return string
444
- */
445
- function getServerUrlEncoding() {
446
- return $this->zendConfig->encoding->serverURI;
447
- }
448
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/Core/AbstractConfiguration.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Base class for the configuration implementation.
6
+ */
7
+ abstract class AbstractConfiguration implements ConfigurationInterface
8
+ {
9
+
10
+ public function getCustomValue($name)
11
+ {
12
+ return null;
13
+ }
14
+
15
+ public function isDebugEnabled()
16
+ {
17
+ return false;
18
+ }
19
+
20
+ public function getRequestProtocol()
21
+ {
22
+ return 'http';
23
+ }
24
+
25
+ public function getServerAddress()
26
+ {
27
+ return null;
28
+ }
29
+
30
+ public function getServerPort()
31
+ {
32
+ return '80';
33
+ }
34
+
35
+ public function getContext()
36
+ {
37
+ return null;
38
+ }
39
+
40
+ public function getChannel()
41
+ {
42
+ return null;
43
+ }
44
+
45
+ public function getLanguage()
46
+ {
47
+ return null;
48
+ }
49
+
50
+ public function isHttpAuthenticationType()
51
+ {
52
+ return false;
53
+ }
54
+
55
+ public function isSimpleAuthenticationType()
56
+ {
57
+ return false;
58
+ }
59
+
60
+ public function isAdvancedAuthenticationType()
61
+ {
62
+ return false;
63
+ }
64
+
65
+ private function retrieveType()
66
+ {
67
+ return null;
68
+ }
69
+
70
+ public function getUserName()
71
+ {
72
+ return null;
73
+ }
74
+
75
+ public function getPassword()
76
+ {
77
+ return null;
78
+ }
79
+
80
+ public function getAuthenticationPrefix()
81
+ {
82
+ return null;
83
+ }
84
+
85
+ public function getAuthenticationPostfix()
86
+ {
87
+ return null;
88
+ }
89
+
90
+ public function getClientMappings()
91
+ {
92
+ return array();
93
+ }
94
+
95
+ public function getServerMappings()
96
+ {
97
+ return array();
98
+ }
99
+
100
+ public function getIgnoredClientParameters()
101
+ {
102
+ return array();
103
+ }
104
+
105
+ public function getIgnoredServerParameters()
106
+ {
107
+ return array();
108
+ }
109
+
110
+ public function getWhitelistClientParameters()
111
+ {
112
+ return array();
113
+ }
114
+
115
+ public function getWhitelistServerParameters()
116
+ {
117
+ return array(
118
+ '/^filter.*/' => true,
119
+ '/^sort.*/' => true,
120
+ '/^substringFilter.*/' => true,
121
+ 'advisorStatus' => true,
122
+ 'callback' => true,
123
+ 'catalog' => true,
124
+ 'channel' => true,
125
+ 'cookieId' => true,
126
+ 'count' => true,
127
+ 'do' => true,
128
+ 'event' => true,
129
+ 'followSearch' => true,
130
+ 'format' => true,
131
+ 'id' => true,
132
+ 'idsOnly' => true,
133
+ 'ignoreForCache' => true,
134
+ 'isArticleNumber' => true,
135
+ 'log' => true,
136
+ 'mainId' => true,
137
+ 'masterId' => true,
138
+ 'maxRecordCount' => true,
139
+ 'maxResults' => true,
140
+ 'navigation' => true,
141
+ 'noArticleNumberSearch' => true,
142
+ 'omitContextName' => true,
143
+ 'origPageSize' => true,
144
+ 'origPos' => true,
145
+ 'page' => true,
146
+ 'pageSize' => true,
147
+ 'pos' => true,
148
+ 'price' => true,
149
+ 'productNumber' => true,
150
+ 'productsPerPage' => true,
151
+ 'query' => true,
152
+ 'queryFromSuggest' => true,
153
+ 'searchField' => true,
154
+ 'sid' => true,
155
+ 'simi' => true,
156
+ 'title' => true,
157
+ 'useAsn' => true,
158
+ 'useAso' => true,
159
+ 'useCampaigns' => true,
160
+ 'useFoundWords' => true,
161
+ 'useKeywords' => true,
162
+ 'usePersonalization' => true,
163
+ 'userId' => true,
164
+ 'userInput' => true,
165
+ 'useSemanticEnhancer' => true,
166
+ 'verbose' => true,
167
+ 'wordCount' => true
168
+ );
169
+ }
170
+
171
+ public function getRequiredClientParameters()
172
+ {
173
+ return array();
174
+ }
175
+
176
+ public function getRequiredServerParameters()
177
+ {
178
+ return array();
179
+ }
180
+
181
+ public function getDefaultConnectTimeout()
182
+ {
183
+ return 2;
184
+ }
185
+
186
+ public function getDefaultTimeout()
187
+ {
188
+ return 4;
189
+ }
190
+
191
+ public function getSuggestConnectTimeout()
192
+ {
193
+ return 2;
194
+ }
195
+
196
+ public function getSuggestTimeout()
197
+ {
198
+ return 2;
199
+ }
200
+
201
+ public function getTrackingConnectTimeout()
202
+ {
203
+ return 2;
204
+ }
205
+
206
+ public function getTrackingTimeout()
207
+ {
208
+ return 2;
209
+ }
210
+
211
+ public function getImportConnectTimeout()
212
+ {
213
+ return 10;
214
+ }
215
+
216
+ public function getImportTimeout()
217
+ {
218
+ return 360;
219
+ }
220
+
221
+ public function getPageContentEncoding()
222
+ {
223
+ return 'UTF-8';
224
+ }
225
+
226
+ public function getClientUrlEncoding()
227
+ {
228
+ return 'UTF-8';
229
+ }
230
+ }
231
+
lib/FACTFinder/Core/AbstractEncodingConverter.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Takes care of differences in encoding between different participants of the
8
+ * communication. Internal to the library all strings are encoded as UTF-8, so
9
+ * the methods of this class are only for converting to and from UTF-8. The
10
+ * source and target encodings are determined by the configuration.
11
+ * This abstract class does not specify how the actual conversion of a single
12
+ * string is done. Create a subclass to implement the conversion method.
13
+ * Also note that none of these methods handle URL en- or decoding but only deal
14
+ * with plain character encodings.
15
+ */
16
+ abstract class AbstractEncodingConverter
17
+ {
18
+ const LIBRARY_ENCODING = 'UTF-8';
19
+
20
+ /**
21
+ * @var FACTFinder\Util\LoggerInterface
22
+ */
23
+ private $log;
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ protected $pageContentEncoding;
29
+ /**
30
+ * @var string
31
+ */
32
+ protected $clientUrlEncoding;
33
+
34
+ /**
35
+ * @param string $loggerClass Class name of logger to use. The class should
36
+ * implement FACTFinder\Util\LoggerInterface.
37
+ * @param ConfigurationInterface $configuration Configuration object to use.
38
+ */
39
+ function __construct(
40
+ $loggerClass,
41
+ ConfigurationInterface $configuration
42
+ ) {
43
+ $this->log = $loggerClass::getLogger(__CLASS__);
44
+
45
+ $this->pageContentEncoding = $configuration->getPageContentEncoding();
46
+ $this->clientUrlEncoding = $configuration->getClientUrlEncoding();
47
+ }
48
+
49
+ abstract protected function convertString($inCharset, $outCharset, $string);
50
+
51
+ /**
52
+ * Converts data from $inCharset to $outCharset.
53
+ * @param mixed $data If a string is given, it's encoding will be converted.
54
+ * If an associative array is given, keys and values will be
55
+ * converted recursively. All other data types will be returned
56
+ * unchanged.
57
+ * @return mixed
58
+ */
59
+ protected function convert($inCharset, $outCharset, $data)
60
+ {
61
+ if($inCharset == $outCharset) {
62
+ return $data;
63
+ }
64
+ return $this->convert_recursive($inCharset, $outCharset, $data);
65
+ }
66
+
67
+ /**
68
+ * Converts data from $inCharset to $outCharset.
69
+ * @param mixed $data If a string is given, it's encoding will be converted.
70
+ * If an associative array is given, keys and values will be
71
+ * converted recursively. All other data types will be returned
72
+ * unchanged.
73
+ * @return mixed
74
+ */
75
+ protected function convert_recursive($inCharset, $outCharset, $data)
76
+ {
77
+ if (FF::isInstanceOf($data, 'Util\Parameters'))
78
+ {
79
+ $result = FF::getInstance(
80
+ 'Util\Parameters',
81
+ $this->convert($inCharset, $outCharset, $data->getArray())
82
+ );
83
+ }
84
+ else if (is_array($data))
85
+ {
86
+ $result = array();
87
+ foreach ($data as $k => $v)
88
+ {
89
+ $k = $this->convert_recursive($inCharset, $outCharset, $k);
90
+ $result[$k] = $this->convert_recursive($inCharset, $outCharset, $v);
91
+ }
92
+ }
93
+ else if (is_string($data))
94
+ {
95
+ $result = $this->convertString($inCharset, $outCharset, $data);
96
+ }
97
+ else
98
+ {
99
+ $result = $data;
100
+ }
101
+
102
+ return $result;
103
+ }
104
+
105
+ /**
106
+ * Converts data held by the library for use on the rendered page.
107
+ * Hence, it converts from the library's encoding (UTF-8) to the configured
108
+ * page content encoding.
109
+ * @param mixed $data Could either be a string or an associative array.
110
+ * @return mixed
111
+ */
112
+ public function encodeContentForPage($data)
113
+ {
114
+ return $this->convert(
115
+ self::LIBRARY_ENCODING,
116
+ $this->pageContentEncoding,
117
+ $data
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Converts data obtained from the client URL for use within the library.
123
+ * Hence, it converts from the configured client URL encoding to the
124
+ * library's encoding (UTF-8).
125
+ * @param mixed $data Data obtained from the client URL. Note that this
126
+ * data should already be URL decoded. Could either be a string or an
127
+ * associative array.
128
+ * @return mixed
129
+ */
130
+ public function decodeClientUrlData($data)
131
+ {
132
+ return $this->convert(
133
+ $this->clientUrlEncoding,
134
+ self::LIBRARY_ENCODING,
135
+ $data
136
+ );
137
+ }
138
+
139
+ /**
140
+ * Converts data held by the library for use in a client URL.
141
+ * Hence, it converts from the configured client URL encoding to the
142
+ * library's encoding (UTF-8).
143
+ * @param mixed $data Data to be used in the client URL. Note that this
144
+ * data should not yet be URL encoded. Could either be a string or an
145
+ * associative array.
146
+ * @return mixed
147
+ */
148
+ public function encodeClientUrlData($data)
149
+ {
150
+ return $this->convert(
151
+ self::LIBRARY_ENCODING,
152
+ $this->clientUrlEncoding,
153
+ $data
154
+ );
155
+ }
156
+ }
lib/FACTFinder/Core/Client/RequestParser.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Client;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Extracts several data from the request made to the client.
8
+ */
9
+ class RequestParser
10
+ {
11
+ protected $clientRequestParameters;
12
+ protected $serverRequestParameters;
13
+ protected $requestTarget;
14
+
15
+ /**
16
+ * @var FACTFinder\Util\LoggerInterface
17
+ */
18
+ private $log;
19
+
20
+ /**
21
+ * @var ConfigurationInterface
22
+ */
23
+ protected $configuration;
24
+
25
+ /**
26
+ * @var AbstractEncodingConverter
27
+ */
28
+ protected $encodingConverter;
29
+
30
+ /**
31
+ * @var ParametersConverter
32
+ */
33
+ protected $parametersConverter;
34
+
35
+ /**
36
+ * @param string $loggerClass Class name of logger to use. The class should
37
+ * implement FACTFinder\Util\LoggerInterface.
38
+ * @param ConfigurationInterface $configuration
39
+ * @param AbstractEncodingConverter $encodingConverter
40
+ */
41
+ function __construct(
42
+ $loggerClass,
43
+ \FACTFinder\Core\ConfigurationInterface $configuration,
44
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
45
+ ) {
46
+ $this->log = $loggerClass::getLogger(__CLASS__);
47
+ $this->configuration = $configuration;
48
+ $this->encodingConverter = $encodingConverter;
49
+ $this->parametersConverter = FF::getInstance(
50
+ 'Core\ParametersConverter',
51
+ $loggerClass,
52
+ $configuration
53
+ );
54
+ }
55
+
56
+ /**
57
+ * Loads parameters from the request and returns a Parameter object.
58
+ * Also takes care of encoding conversion if necessary. Finally it will make
59
+ * all necessary conversions according to the ignore/require/mapping
60
+ * directives given in the configuration for the server. Use this method
61
+ * for any other part of the library that needs the request parameters.
62
+ *
63
+ * @return Parameters Array of UTF-8 encoded and converted parameters
64
+ */
65
+ public function getRequestParameters()
66
+ {
67
+ if (is_null($this->serverRequestParameters))
68
+ {
69
+ $clientParameters = $this->getClientRequestParameters();
70
+ $this->serverRequestParameters =
71
+ $this->parametersConverter->convertClientToServerParameters(
72
+ $clientParameters
73
+ );
74
+ }
75
+
76
+ return $this->serverRequestParameters;
77
+ }
78
+
79
+ /**
80
+ * Loads parameters from the request and returns a Parameter object.
81
+ * Also takes care of encoding conversion if necessary. However, the
82
+ * parameters themselves are not converted (that is ignore, require and
83
+ * mapping directives in the configuration are not taken into account).
84
+ *
85
+ * You won't usually need this method unless you really want to get access
86
+ * to some parameters that would be ignored or mapped otherwise.
87
+ *
88
+ * For use with any other part of the library, use getRequestParameters()
89
+ * instead, which converts the parameters for usage with the server.
90
+ *
91
+ * @return Parameters Array of UTF-8 encoded parameters
92
+ */
93
+ public function getClientRequestParameters()
94
+ {
95
+ if (is_null($this->clientRequestParameters))
96
+ {
97
+ if (isset($_SERVER['QUERY_STRING']))
98
+ {
99
+ // TODO: Respect variables_order so that conflicting variables
100
+ // lead to the same result as in $_REQUEST (save for
101
+ // $_COOKIE variables). This todo also goes for the second
102
+ // alternative.
103
+ $parameters = FF::getInstance(
104
+ 'Util\Parameters',
105
+ $_SERVER['QUERY_STRING']
106
+ );
107
+
108
+ $data = $_POST;
109
+
110
+ if (!empty($data)) {
111
+ foreach ($data as $key => $value) {
112
+ if (is_array($value)) {
113
+ unset($data[$key]);
114
+ }
115
+ }
116
+ }
117
+
118
+ $parameters->setAll($data);
119
+ }
120
+ else if (isset($_GET))
121
+ {
122
+ $this->log->warn('$_SERVER[\'QUERY_STRING\'] is not available. '
123
+ . 'Using $_GET instead. This may cause problems '
124
+ . 'if the query string contains parameters with '
125
+ . 'non-[a-zA-Z0-9_] characters.');
126
+
127
+ // Don't use $_REQUEST, because it also contains $_COOKIE.
128
+ // Note that we don't have to URL decode here, because _GET is
129
+ // already URL decoded.
130
+ $parameters = FF::getInstance(
131
+ 'Util\Parameters',
132
+ array_merge($_POST, $_GET)
133
+ );
134
+ }
135
+ else
136
+ {
137
+ // For CLI use:
138
+ $parameters = FF::getInstance('Util\Parameters');
139
+ }
140
+
141
+ // Convert encoding and then the parameters themselves
142
+ $this->clientRequestParameters = $this->encodingConverter != null ? $this->encodingConverter->decodeClientUrlData($parameters) : $parameters;
143
+
144
+ }
145
+
146
+ return $this->clientRequestParameters;
147
+ }
148
+
149
+ /**
150
+ * Get target of the current request.
151
+ *
152
+ * @return string request target
153
+ */
154
+ public function getRequestTarget()
155
+ {
156
+ if ($this->requestTarget === null)
157
+ {
158
+ // Workaround for some servers (IIS) which do not provide
159
+ // $_SERVER['REQUEST_URI']. Taken from
160
+ // http://php.net/manual/en/reserved.variables.server.php#108186
161
+ if(!isset($_SERVER['REQUEST_URI'])) {
162
+ $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
163
+ if(isset($_SERVER['QUERY_STRING'])) {
164
+ $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
165
+ }
166
+ }
167
+
168
+ if (strpos($_SERVER['REQUEST_URI'], '?') === false)
169
+ $this->requestTarget = $_SERVER['REQUEST_URI'];
170
+ else
171
+ {
172
+ $parts = explode('?', $_SERVER['REQUEST_URI']);
173
+ $this->requestTarget = $parts[0];
174
+ }
175
+
176
+ // Use rawurldecode() so that +'s are not converted to spaces.
177
+ $this->requestTarget = rawurldecode($this->requestTarget);
178
+ if ($this->encodingConverter != null)
179
+ {
180
+ $this->requestTarget = $this->encodingConverter ->decodeClientUrlData($this->requestTarget);
181
+ }
182
+ }
183
+ return $this->requestTarget;
184
+ }
185
+ }
lib/FACTFinder/Core/Client/UrlBuilder.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Client;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Generates URLs to be used in requests to the client.
8
+ */
9
+ class UrlBuilder
10
+ {
11
+ /**
12
+ * @var FACTFinder\Util\LoggerInterface
13
+ */
14
+ private $log;
15
+
16
+ /**
17
+ * @var FACTFinder\Core\ParametersConverter
18
+ */
19
+ private $parametersConverter;
20
+
21
+ /**
22
+ * @var FACTFinder\Core\Client\RequestParser
23
+ */
24
+ private $requestParser;
25
+
26
+ /**
27
+ * @var FACTFinder\Core\AbstractEncodingConverter
28
+ */
29
+ private $encodingConverter;
30
+
31
+ public function __construct(
32
+ $loggerClass,
33
+ \FACTFinder\Core\ConfigurationInterface $configuration,
34
+ \FACTFinder\Core\Client\RequestParser $requestParser,
35
+ \FACTFinder\Core\AbstractEncodingConverter $encodingConverter = null
36
+ ) {
37
+ $this->log = $loggerClass::getLogger(__CLASS__);
38
+
39
+ $this->parametersConverter = FF::getInstance(
40
+ 'Core\ParametersConverter',
41
+ $loggerClass,
42
+ $configuration
43
+ );
44
+ $this->requestParser = $requestParser;
45
+ $this->encodingConverter = $encodingConverter;
46
+ }
47
+
48
+ /**
49
+ * Generates a link to be used on the page that leads to the client from a
50
+ * set of server parameters. Note that the link will still be UTF-8 encoded.
51
+ * If the page uses a different encoding, conversion to that encoding has to
52
+ * be done when actually rendering the string to the page.
53
+ *
54
+ * TODO: Should the signature be more similar to that of \Server\UrlBuilder?
55
+ *
56
+ * @param FACTFinder\Util\Parameters $parameters The server parameters that
57
+ * should be retrieved when the link is followed.
58
+ * @param string $target An optional request target. If omitted, the target
59
+ * of the current request will be used. For instance, this parameter
60
+ * can be used if a product detail page needs a different target.
61
+ *
62
+ * @return string
63
+ */
64
+ public function generateUrl($parameters, $target = null)
65
+ {
66
+ $parameters = $this->parametersConverter
67
+ ->convertServerToClientParameters($parameters);
68
+
69
+ $parameters = $this->encodingConverter != null ? $this->encodingConverter->encodeClientUrlData($parameters) : $parameters;
70
+
71
+ if (!is_string($target))
72
+ $target = $this->requestParser->getRequestTarget();
73
+
74
+ $url = $target . '?' . $parameters->toPhpQueryString();
75
+ return $url;
76
+ }
77
+ }
lib/FACTFinder/Core/ConfigurationInterface.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Interface for all necessary configuration data to get the library running
6
+ * (plus, any necessary custom values).
7
+ */
8
+ interface ConfigurationInterface
9
+ {
10
+ /**
11
+ * @return bool
12
+ */
13
+ public function isDebugEnabled();
14
+
15
+ /**
16
+ * @param string name
17
+ * @return string value
18
+ */
19
+ public function getCustomValue($name);
20
+
21
+ /**
22
+ * @return string
23
+ */
24
+ public function getRequestProtocol();
25
+
26
+ /**
27
+ * @return string
28
+ */
29
+ public function getServerAddress();
30
+
31
+ /**
32
+ * @return int
33
+ */
34
+ public function getServerPort();
35
+
36
+ /**
37
+ * @return string
38
+ */
39
+ public function getContext();
40
+
41
+ /**
42
+ * @return string
43
+ */
44
+ public function getChannel();
45
+
46
+ /**
47
+ * @return string
48
+ */
49
+ public function getLanguage();
50
+
51
+ /**
52
+ * @return boolean
53
+ */
54
+ public function isHttpAuthenticationType();
55
+
56
+ /**
57
+ * @return boolean
58
+ */
59
+ public function isSimpleAuthenticationType();
60
+
61
+ /**
62
+ * @return boolean
63
+ */
64
+ public function isAdvancedAuthenticationType();
65
+
66
+ /**
67
+ * @return string
68
+ */
69
+ public function getUserName();
70
+
71
+ /**
72
+ * @return string
73
+ */
74
+ public function getPassword();
75
+
76
+ /**
77
+ * @return string
78
+ */
79
+ public function getAuthenticationPrefix();
80
+
81
+ /**
82
+ * @return string
83
+ */
84
+ public function getAuthenticationPostfix();
85
+
86
+ /**
87
+ * Get mappings from server to client parameters.
88
+ *
89
+ * @return array
90
+ */
91
+ public function getClientMappings();
92
+
93
+ /**
94
+ * Get mappings from client to server parameters.
95
+ *
96
+ * @return array
97
+ */
98
+ public function getServerMappings();
99
+
100
+ /**
101
+ * Get parameters which should be ignored in client URLs.
102
+ *
103
+ * @return array with string as key and boolean true as value for each item
104
+ */
105
+ public function getIgnoredClientParameters();
106
+
107
+ /**
108
+ * Get parameters which should be ignored in server URLs.
109
+ *
110
+ * @return array with string as key and boolean true as value for each item
111
+ */
112
+ public function getIgnoredServerParameters();
113
+
114
+ /**
115
+ * Get parameters which are allowed in client URLs.
116
+ *
117
+ * @return array with string as key and boolean true as value for each item
118
+ */
119
+ public function getWhitelistClientParameters();
120
+
121
+ /**
122
+ * Get parameters which are allowed in server URLs.
123
+ *
124
+ * @return array with string as key and boolean true as value for each item
125
+ */
126
+ public function getWhitelistServerParameters();
127
+
128
+ /**
129
+ * Get parameters which are required in client URLs.
130
+ *
131
+ * @return array with parameter name as key and default value as value.
132
+ */
133
+ public function getRequiredClientParameters();
134
+
135
+ /**
136
+ * Get parameters which are required in server URLs.
137
+ *
138
+ * @return array with parameter name as key and default value as value.
139
+ */
140
+ public function getRequiredServerParameters();
141
+
142
+ /**
143
+ * Get default connect timeout for all adapters.
144
+ *
145
+ * @return int
146
+ */
147
+ public function getDefaultConnectTimeout();
148
+
149
+ /**
150
+ * Get default timeout for all adapters.
151
+ *
152
+ * @return int
153
+ */
154
+ public function getDefaultTimeout();
155
+
156
+ /**
157
+ * Get connect timeout for Suggest adapter.
158
+ *
159
+ * @return int
160
+ */
161
+ public function getSuggestConnectTimeout();
162
+
163
+ /**
164
+ * Get timeout for Suggest adapter.
165
+ *
166
+ * @return int
167
+ */
168
+ public function getSuggestTimeout();
169
+
170
+ /**
171
+ * Get connect timeout for Tracking adapter.
172
+ *
173
+ * @return int
174
+ */
175
+ public function getTrackingConnectTimeout();
176
+
177
+ /**
178
+ * Get timeout for Tracking adapter.
179
+ *
180
+ * @return int
181
+ */
182
+ public function getTrackingTimeout();
183
+
184
+ /**
185
+ * Get connect timeout for Import adapter.
186
+ *
187
+ * @return int
188
+ */
189
+ public function getImportConnectTimeout();
190
+
191
+ /**
192
+ * Get timeout for Import adapter-
193
+ *
194
+ * @return int
195
+ */
196
+ public function getImportTimeout();
197
+
198
+ /**
199
+ * Get encoding for content to be sent to the browser.
200
+ *
201
+ * @return string
202
+ */
203
+ public function getPageContentEncoding();
204
+
205
+ /**
206
+ * Get encoding for URLs of the client.
207
+ *
208
+ * @return string
209
+ */
210
+ public function getClientUrlEncoding();
211
+ }
212
+
lib/FACTFinder/Core/IConvEncodingConverter.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Implements the AbstractEncodingConverter using the iconv module.
6
+ */
7
+ class IConvEncodingConverter extends AbstractEncodingConverter
8
+ {
9
+ function __construct(
10
+ $loggerClass,
11
+ ConfigurationInterface $configuration
12
+ ) {
13
+ parent::__construct($loggerClass, $configuration);
14
+ $this->log = $loggerClass::getLogger(__CLASS__);
15
+ }
16
+
17
+ protected function convertString($inCharset, $outCharset, $string)
18
+ {
19
+ if ($inCharset == $outCharset
20
+ || empty($inCharset)
21
+ || empty($outCharset)
22
+ ) {
23
+ return $string;
24
+ }
25
+ // See http://www.php.net/manual/en/function.iconv.php for more
26
+ // information on '//TRANSLIT'.
27
+ $result = iconv($inCharset, $outCharset.'//TRANSLIT', $string);
28
+
29
+ if ($result === false)
30
+ {
31
+ $this->log->warn(
32
+ "Conversion from $inCharset to $outCharset not possible. "
33
+ . "The string is still encoded with $inCharset."
34
+ );
35
+ $result = $string;
36
+ }
37
+
38
+ return $result;
39
+ }
40
+ }
lib/FACTFinder/Core/ManualConfiguration.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Quick-and-dirty implementation of ConfigurationInterface which requires all
6
+ * values to be set manually through the magic __set(). Really only useful for
7
+ * testing.
8
+ */
9
+ class ManualConfiguration extends AbstractConfiguration
10
+ {
11
+ const HTTP_AUTHENTICATION = 'http';
12
+ const SIMPLE_AUTHENTICATION = 'simple';
13
+ const ADVANCED_AUTHENTICATION = 'advanced';
14
+
15
+ private $configuration ;
16
+
17
+ function __construct($configuration = null)
18
+ {
19
+ $this->configuration = $configuration ?: array();
20
+ }
21
+
22
+ function __set($name, $value)
23
+ {
24
+ $this->configuration[$name] = $value;
25
+ }
26
+
27
+ public function getCustomValue($name)
28
+ {
29
+ return $this->configuration[$name];
30
+ }
31
+
32
+ public function isDebugEnabled()
33
+ {
34
+ return $this->configuration['debug'];
35
+ }
36
+
37
+ public function getRequestProtocol()
38
+ {
39
+ return $this->configuration['requestProtocol'];
40
+ }
41
+
42
+ public function getServerAddress()
43
+ {
44
+ return $this->configuration['serverAddress'];
45
+ }
46
+
47
+ public function getServerPort()
48
+ {
49
+ return $this->configuration['port'];
50
+ }
51
+
52
+ public function getContext()
53
+ {
54
+ return $this->configuration['context'];
55
+ }
56
+
57
+ public function getChannel()
58
+ {
59
+ return $this->configuration['channel'];
60
+ }
61
+
62
+ public function getLanguage()
63
+ {
64
+ return $this->configuration['language'];
65
+ }
66
+
67
+ public function isHttpAuthenticationType()
68
+ {
69
+ return $this->retrieveType() == self::HTTP_AUTHENTICATION;
70
+ }
71
+
72
+ public function isSimpleAuthenticationType()
73
+ {
74
+ return $this->retrieveType() == self::SIMPLE_AUTHENTICATION;
75
+ }
76
+
77
+ public function isAdvancedAuthenticationType()
78
+ {
79
+ return $this->retrieveType() == self::ADVANCED_AUTHENTICATION;
80
+ }
81
+
82
+ private function retrieveType()
83
+ {
84
+ return $this->configuration['authenticationType'];
85
+ }
86
+
87
+ public function getUserName()
88
+ {
89
+ return $this->configuration['userName'];
90
+ }
91
+
92
+ public function getPassword()
93
+ {
94
+ return $this->configuration['password'];
95
+ }
96
+
97
+ public function getAuthenticationPrefix()
98
+ {
99
+ return $this->configuration['authenticationPrefix'];
100
+ }
101
+
102
+ public function getAuthenticationPostfix()
103
+ {
104
+ return $this->configuration['authenticationPostfix'];
105
+ }
106
+
107
+ public function getClientMappings()
108
+ {
109
+ return $this->configuration['clientMappings'];
110
+ }
111
+
112
+ public function getServerMappings()
113
+ {
114
+ return $this->configuration['serverMappings'];
115
+ }
116
+
117
+ public function getIgnoredClientParameters()
118
+ {
119
+ return $this->configuration['ignoredClientParameters'];
120
+ }
121
+
122
+ public function getIgnoredServerParameters()
123
+ {
124
+ return $this->configuration['ignoredServerParameters'];
125
+ }
126
+
127
+ public function getWhitelistClientParameters()
128
+ {
129
+ return $this->configuration['whitelistClientParameters'];
130
+ }
131
+
132
+ public function getWhitelistServerParameters()
133
+ {
134
+ return $this->configuration['whitelistServerParameters'];
135
+ }
136
+
137
+ public function getRequiredClientParameters()
138
+ {
139
+ return $this->configuration['requiredClientParameters'];
140
+ }
141
+
142
+ public function getRequiredServerParameters()
143
+ {
144
+ return $this->configuration['requiredServerParameters'];
145
+ }
146
+
147
+ public function getDefaultConnectTimeout()
148
+ {
149
+ return $this->configuration['defaultConnectTimeout'];
150
+ }
151
+
152
+ public function getDefaultTimeout()
153
+ {
154
+ return $this->configuration['defaultTimeout'];
155
+ }
156
+
157
+ public function getSuggestConnectTimeout()
158
+ {
159
+ return $this->configuration['suggestConnectTimeout'];
160
+ }
161
+
162
+ public function getSuggestTimeout()
163
+ {
164
+ return $this->configuration['suggestTimeout'];
165
+ }
166
+
167
+ public function getTrackingConnectTimeout()
168
+ {
169
+ return $this->configuration['trackingConnectTimeout'];
170
+ }
171
+
172
+ public function getTrackingTimeout()
173
+ {
174
+ return $this->configuration['trackingTimeout'];
175
+ }
176
+
177
+ public function getImportConnectTimeout()
178
+ {
179
+ return $this->configuration['importConnectTimeout'];
180
+ }
181
+
182
+ public function getImportTimeout()
183
+ {
184
+ return $this->configuration['importTimeout'];
185
+ }
186
+
187
+ public function getPageContentEncoding()
188
+ {
189
+ return $this->configuration['pageContentEncoding'];
190
+ }
191
+
192
+ public function getClientUrlEncoding()
193
+ {
194
+ return $this->configuration['clientUrlEncoding'];
195
+ }
196
+ }
197
+
lib/FACTFinder/Core/Page/.gitignore ADDED
File without changes
lib/FACTFinder/Core/ParametersConverter.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Handles the conversion of parameters between requests to the client and
6
+ * requests to the FACT-Finder server (and vice-versa).
7
+ */
8
+ class ParametersConverter
9
+ {
10
+ /**
11
+ * @var FACTFinder\Util\LoggerInterface
12
+ */
13
+ private $log;
14
+
15
+ /**
16
+ * @var ConfigurationInterface
17
+ */
18
+ protected $configuration;
19
+
20
+ /**
21
+ * @param string $loggerClass Class name of logger to use. The class should
22
+ * implement FACTFinder\Util\LoggerInterface.
23
+ * @param ConfigurationInterface $configuration Configuration object to use.
24
+ */
25
+ public function __construct(
26
+ $loggerClass,
27
+ ConfigurationInterface $configuration
28
+ ) {
29
+ $this->log = $loggerClass::getLogger(__CLASS__);
30
+ $this->configuration = $configuration;
31
+ }
32
+
33
+ /**
34
+ * @param Parameters $clientParameters Parameters obtained from a request to
35
+ * the client.
36
+ * @return Parameters Parameters ready for use with FACT-Finder.
37
+ */
38
+ public function convertClientToServerParameters($clientParameters)
39
+ {
40
+ $result = clone $clientParameters;
41
+ $this->applyParameterMappings($result, $this->configuration->getServerMappings());
42
+ $this->removeIgnoredParameters($result, $this->configuration->getIgnoredServerParameters());
43
+ $this->applyWhitelist($result, $this->configuration->getWhitelistServerParameters());
44
+ $this->ensureChannelParameter($result);
45
+ $this->addRequiredParameters($result, $this->configuration->getRequiredServerParameters());
46
+
47
+ return $result;
48
+ }
49
+
50
+ /**
51
+ * @param Parameters $clientParameters Parameters obtained from FACT-Finder.
52
+ * @return Parameters Parameters ready for use in requests to the client.
53
+ */
54
+ public function convertServerToClientParameters($serverParameters)
55
+ {
56
+ $result = clone $serverParameters;
57
+ $this->applyParameterMappings($result, $this->configuration->getClientMappings());
58
+ $this->removeIgnoredParameters($result, $this->configuration->getIgnoredClientParameters());
59
+ $this->applyWhitelist($result, $this->configuration->getWhitelistClientParameters());
60
+ $this->addRequiredParameters($result, $this->configuration->getRequiredClientParameters());
61
+
62
+ return $result;
63
+ }
64
+
65
+ /**
66
+ * Changes the keys in a Parameters object according to the given mapping
67
+ * rules.
68
+ * @param Parameters $parameters Parameters to be modified.
69
+ * @param string[] $mappingRules Associative array of mapping rules.
70
+ * Parameter names will be mapped from keys to values of this array.
71
+ */
72
+ protected function applyParameterMappings($parameters, $mappingRules)
73
+ {
74
+ foreach ($mappingRules as $k => $v)
75
+ {
76
+ if ($k != $v && isset($parameters[$k]))
77
+ {
78
+ $parameters[$v] = $parameters[$k];
79
+ unset($parameters[$k]);
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Removes keys from a Parameters object according to the given ignore
86
+ * rules. It basically turns the parameters into the set difference of the
87
+ * parameters and the ignore rules based on keys.
88
+ * @param Parameters $parameters Parameters to be modified.
89
+ * @param bool[] $ignoreRules Array of parameters to be ignored. The keys
90
+ * are the parameter names, the values are simply "true", but could
91
+ * technically have any value.
92
+ */
93
+ protected function removeIgnoredParameters($parameters, $ignoreRules)
94
+ {
95
+ foreach ($ignoreRules as $k => $v)
96
+ unset($parameters[$k]);
97
+ }
98
+
99
+ /**
100
+ * Removes keys from a Parameters object according to the given whitelist rules.
101
+ * An empty whitelist means do NOT apply any whitelist (anything is allowed).
102
+ * It removes any keys that are not keys in the given whitelist array aswell.
103
+ * If the key of any rule starts with '/' the key is interpreted as a regular expression to be matched against.
104
+ * @param type $parameters
105
+ * @param bool[] $whitelistRules Array of parameters to be allowed. The keys
106
+ * are the parameter names, the values are simply "true", but could
107
+ * technically have any value.
108
+ */
109
+ protected function applyWhitelist($parameters, $whitelistRules)
110
+ {
111
+ //do not apply empty whitelist as this means no whitelist desired
112
+ if(empty($whitelistRules)) {
113
+ return;
114
+ }
115
+ //collect all keys of parameters that pass any whitelist rule
116
+ $allowedKeys = array();
117
+ $keys = array_keys($parameters->getArray());
118
+ foreach ($whitelistRules as $rule => $v) {
119
+ if(strpos($rule, '/') === 0) {
120
+ $allowedKeys = array_merge($allowedKeys, preg_grep($rule, $keys));
121
+ } else {
122
+ $allowedKeys[] = $rule;
123
+ }
124
+ }
125
+ $allowedKeys = array_flip($allowedKeys);
126
+ //unset any parameters that did not pass any whitelist rule
127
+ foreach($parameters->getArray() as $k => $v) {
128
+ if(!isset($allowedKeys[$k])) {
129
+ unset($parameters[$k]);
130
+ }
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Ensures that the passed parameters object has a "channel" parameter by
136
+ * adding one if necessary.
137
+ * @param Parameters $parameters Parameters to be modifier.
138
+ */
139
+ protected function ensureChannelParameter($parameters)
140
+ {
141
+ if (!isset($parameters['channel']) || strlen($parameters['channel']) == 0)
142
+ $parameters['channel'] = $this->configuration->getChannel();
143
+ }
144
+
145
+ /**
146
+ * Adds keys to an array of parameters according to the given require rules.
147
+ * @param Parameters $parameters Parameters to be modified.
148
+ * @param string[] $ignoreRules Array of required parameters. The keys are
149
+ * the names of the required parameter, the values are default values
150
+ * to be used if the parameter is not present.
151
+ */
152
+ protected function addRequiredParameters($parameters, $requireRules)
153
+ {
154
+ foreach ($requireRules as $k => $v)
155
+ if (!isset($parameters[$k]))
156
+ $parameters[$k] = $v;
157
+ }
158
+ }
lib/FACTFinder/Core/Server/AbstractDataProvider.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ /**
5
+ * Data providers take care of retrieving pre-configured requests with
6
+ * FACT-Finder data, including the network connection if necessary.
7
+ */
8
+ abstract class AbstractDataProvider
9
+ {
10
+ /**
11
+ * @var \FACTFinder\Util\LoggerInterface
12
+ */
13
+ private $log;
14
+
15
+ /**
16
+ * @var \FACTFinder\Core\ConfigurationInterface
17
+ */
18
+ protected $configuration;
19
+
20
+ /**
21
+ * @var ConnectionData[] Keys are IDs to identify each connection data
22
+ * object.
23
+ */
24
+ protected $connectionData;
25
+
26
+ /**
27
+ * @var int
28
+ */
29
+ static private $nextID = 0;
30
+
31
+ public function __construct(
32
+ $loggerClass,
33
+ \FACTFinder\Core\ConfigurationInterface $configuration
34
+ ) {
35
+ $this->log = $loggerClass::getLogger(__CLASS__);
36
+ $this->configuration = $configuration;
37
+
38
+ $this->connectionData = array();
39
+ }
40
+
41
+ /**
42
+ * Make a connection data object known to the data provider and obtain an ID
43
+ * for it (basically, a handle).
44
+ *
45
+ * @param ConnectionData $connectionData The connection data object to be
46
+ * registered.
47
+ *
48
+ * @param int The ID by which to refer to the connection data in the future.
49
+ *
50
+ * @throws InvalidArgumentException if the $id is already in use.
51
+ */
52
+ public function register(ConnectionData $connectionData)
53
+ {
54
+ $id = self::$nextID++;
55
+
56
+ $this->connectionData[$id] = $connectionData;
57
+
58
+ $this->log->debug("Registered connection data for ID $id.");
59
+
60
+ return $id;
61
+ }
62
+
63
+ /**
64
+ * Remove all references to the connection data object identified by $id.
65
+ *
66
+ * @param mixed $id The ID corresponding to the connection data object to be
67
+ * removed from the DataProvider.
68
+ */
69
+ public function unregister($id)
70
+ {
71
+ unset($this->connectionData[$id]);
72
+
73
+ $this->log->debug("Unregistered connection data for ID $id.");
74
+ }
75
+
76
+ /**
77
+ * Set the number of seconds to wait while trying to connect. Any particular
78
+ * implementation of this abstract class is free to ignore this timeout, but
79
+ * it should respect it if the underlying connection mechanism allows.
80
+ *
81
+ * @param mixed $id The ID of the connection data for which to set the
82
+ * timeout.
83
+ * @param int $timeout The timeout in seconds.
84
+ */
85
+ abstract public function setConnectTimeout($id, $timeout);
86
+
87
+ /**
88
+ * Set the number of seconds to wait for the entire request to complete. Any
89
+ * particular implementation of this abstract class is free to ignore this
90
+ * timeout, but it should respect it if the underlying connection mechanism
91
+ * allows.
92
+ *
93
+ * @param mixed $id The ID of the connection data for which to set the
94
+ * timeout.
95
+ * @param int $timeout The timeout in seconds.
96
+ */
97
+ abstract public function setTimeout($id, $timeout);
98
+
99
+ /**
100
+ * Load a response based on the current state of the connection data
101
+ * corresponding to $id and fill that ConnectionData object with this
102
+ * response.
103
+ *
104
+ * @param mixed $id The ID of the connection data for which to retrieve a
105
+ * response.
106
+ *
107
+ * @return void The response is NOT returned by this function. It has to be
108
+ * obtained directly from the ConnectionData object.
109
+ */
110
+ abstract public function loadResponse($id);
111
+ }
lib/FACTFinder/Core/Server/ConnectionData.php ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Represents all data belonging to a single connection. It holds all data
8
+ * necessary to configure a request and can also be filled with the
9
+ * corresponding response.
10
+ */
11
+ class ConnectionData
12
+ {
13
+ /**
14
+ * @var \FACTFinder\Util\Parameters
15
+ */
16
+ private $httpHeaderFields;
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ private $action;
22
+
23
+ /**
24
+ * @var \FACTFinder\Util\Parameters
25
+ */
26
+ private $parameters;
27
+
28
+ /**
29
+ * @var mixed[]
30
+ */
31
+ private $connectionOptions = array();
32
+
33
+ /**
34
+ * @var Response
35
+ */
36
+ private $response;
37
+
38
+ /**
39
+ * @var string
40
+ */
41
+ private $previousUrl;
42
+
43
+ /**
44
+ * Optionally takes a Parameters object to initialize the query parameters.
45
+ * @param \FACTFinder\Util\Parameters $parameters
46
+ * @return type
47
+ */
48
+ public function __construct($parameters = null)
49
+ {
50
+ if (FF::isInstanceOf($parameters, 'Util\Parameters'))
51
+ $this->parameters = $parameters;
52
+ else
53
+ $this->parameters = FF::getInstance('Util\Parameters');
54
+
55
+ $this->httpHeaderFields = FF::getInstance('Util\Parameters');
56
+ $this->action = '';
57
+ $this->setNullResponse();
58
+ }
59
+
60
+ /**
61
+ * Returns the parameters object used for the connection, on which HTTP
62
+ * header fields can be read and changed.
63
+ *
64
+ * @return \FACTFinder\Util\Parameters
65
+ */
66
+ public function getHttpHeaderFields()
67
+ {
68
+ return $this->httpHeaderFields;
69
+ }
70
+
71
+ /**
72
+ * Set the action to be queried on the FACT-Finder server. e.g. "Search.ff".
73
+ *
74
+ * @param string $action
75
+ */
76
+ public function setAction($action)
77
+ {
78
+ $this->action = $action;
79
+ }
80
+
81
+ /**
82
+ * Get the action to be queried on the FACT-Finder server. e.g. "Search.ff".
83
+ *
84
+ * @return string
85
+ */
86
+ public function getAction()
87
+ {
88
+ return $this->action;
89
+ }
90
+
91
+ /**
92
+ * Returns the parameters object used for the connection, on which query
93
+ * parameters can be read and changed.
94
+ *
95
+ * @return \FACTFinder\Util\Parameters
96
+ */
97
+ public function getParameters()
98
+ {
99
+ return $this->parameters;
100
+ }
101
+
102
+ /**
103
+ * Set an option for the connection. This can be an arbitrary pair of key
104
+ * and value. How this is used depends on the kind of connection that is set
105
+ * up (e.g. cURL or socket). We simply provide an array to store options
106
+ * specific to this connection.
107
+ *
108
+ * @param mixed $name The option's identifier. This can be any value that is
109
+ * a valid array index in PHP (hence, it SHOULD be a string or an
110
+ * integer; all other types will be interpreted as a string).
111
+ * @param mixed $value The option's value.
112
+ */
113
+ public function setConnectionOption($name, $value)
114
+ {
115
+ $this->connectionOptions[$name] = $value;
116
+ }
117
+
118
+ /**
119
+ * Sets all given connection options at once. If an option with the same
120
+ * name already exists, the old value will be replaced. Options that are not
121
+ * contained in the $options parameter will retain their value(s).
122
+ * @param mixed[] $options An array of options. For more information on
123
+ * valid keys and values see setConnectionOption($name, $value).
124
+ */
125
+ public function setConnectionOptions($options)
126
+ {
127
+ // We cannot use array_merge() here, because that does not preserve
128
+ // numeric keys. Implementing this with a loop also has the advantage
129
+ // of not creating a new, third array.
130
+ foreach ($options as $k => $v)
131
+ $this->connectionOptions[$k] = $v;
132
+ }
133
+
134
+ /**
135
+ * @param mixed $name The option's identifier.
136
+ * @return bool
137
+ */
138
+ public function issetConnectionOption($name)
139
+ {
140
+ return isset($this->connectionOptions[$name]);
141
+ }
142
+
143
+ /**
144
+ * @param mixed $name The option's identifier.
145
+ * @return mixed The option's value.
146
+ */
147
+ public function getConnectionOption($name)
148
+ {
149
+ return $this->connectionOptions[$name];
150
+ }
151
+
152
+ /**
153
+ * Get an array of all set connection options.
154
+ * @return mixed[]
155
+ */
156
+ public function getConnectionOptions()
157
+ {
158
+ return $this->connectionOptions;
159
+ }
160
+
161
+ /**
162
+ * Set a response for the current connection settings along with the URL
163
+ * which was used to obtain the response.
164
+ * @param Response $response
165
+ * @param string $url The URL corresponding to $response.
166
+ */
167
+ public function setResponse(Response $response, $url)
168
+ {
169
+ $this->response = $response;
170
+ $this->previousUrl = $url;
171
+ }
172
+
173
+ /**
174
+ * Set a null response - e.g. if the connection could not even be attempted
175
+ * at all.
176
+ */
177
+ public function setNullResponse()
178
+ {
179
+ $this->response = FF::getInstance('Core\Server\NullResponse');
180
+ $this->previousUrl = null;
181
+ }
182
+
183
+ /**
184
+ * Get the response that was most recently set.
185
+ *
186
+ * @return Response
187
+ */
188
+ public function getResponse()
189
+ {
190
+ return $this->response;
191
+ }
192
+
193
+ /**
194
+ * Get the URL corresponding to the currently stored Response.
195
+ *
196
+ * @return string
197
+ */
198
+ public function getPreviousUrl()
199
+ {
200
+ return $this->previousUrl;
201
+ }
202
+ }
lib/FACTFinder/Core/Server/EasyCurlDataProvider.php ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation retrieves the FACT-Finder data by using the "easy cURL
8
+ * interface" (I didn't even make that up; that's what cURL itself calls it:
9
+ * 'easy' as opposed to 'multi').
10
+ * Responses are queried sequentially and lazily and are cached as long as
11
+ * parameters don't change.
12
+ */
13
+ class EasyCurlDataProvider extends AbstractDataProvider
14
+ {
15
+ /**
16
+ * @var \FACTFinder\Util\LoggerInterface
17
+ */
18
+ private $log;
19
+
20
+ /**
21
+ * @var UrlBuilder
22
+ */
23
+ protected $urlBuilder;
24
+
25
+ /**
26
+ * @var \FACTFinder\Util\CurlInterface
27
+ */
28
+ protected $curl;
29
+
30
+ protected $defaultCurlOptions;
31
+ protected $necessaryCurlOptions;
32
+
33
+ public function __construct(
34
+ $loggerClass,
35
+ \FACTFinder\Core\ConfigurationInterface $configuration,
36
+ \FACTFinder\Util\CurlInterface $curl,
37
+ UrlBuilder $urlBuilder
38
+ ) {
39
+ parent::__construct($loggerClass, $configuration);
40
+
41
+ $this->log = $loggerClass::getLogger(__CLASS__);
42
+
43
+ $this->urlBuilder = $urlBuilder;
44
+
45
+ $this->curl = $curl;
46
+
47
+ $this->defaultCurlOptions = array(
48
+ CURLOPT_CONNECTTIMEOUT => $this->configuration->getDefaultConnectTimeout(),
49
+ CURLOPT_TIMEOUT => $this->configuration->getDefaultTimeout(),
50
+ CURLOPT_SSL_VERIFYPEER => false,
51
+ CURLOPT_SSL_VERIFYHOST => false,
52
+ CURLOPT_ENCODING => '',
53
+ );
54
+
55
+ $this->necessaryCurlOptions = array(
56
+ CURLOPT_RETURNTRANSFER => true,
57
+ );
58
+ }
59
+
60
+ public function setConnectTimeout($id, $timeout)
61
+ {
62
+ if (!isset($this->connectionData[$id]))
63
+ throw new \InvalidArgumentException('Tried to set timeout for invalid ID $id.');
64
+
65
+ $this->connectionData[$id]->setConnectionOption(
66
+ CURLOPT_CONNECTTIMEOUT,
67
+ $timeout
68
+ );
69
+ }
70
+
71
+ public function setTimeout($id, $timeout)
72
+ {
73
+ if (!isset($this->connectionData[$id]))
74
+ throw new \InvalidArgumentException('Tried to set timeout for invalid ID $id.');
75
+
76
+ $this->connectionData[$id]->setConnectionOption(
77
+ CURLOPT_TIMEOUT,
78
+ $timeout
79
+ );
80
+ }
81
+
82
+ // TODO: Could this be refactored some more?
83
+ public function loadResponse($id)
84
+ {
85
+ if (!isset($this->connectionData[$id]))
86
+ throw new \InvalidArgumentException('Tried to get response for invalid ID $id.');
87
+
88
+ if (!$this->hasUrlChanged($id))
89
+ return;
90
+
91
+ $connectionData = $this->connectionData[$id];
92
+
93
+ $action = $connectionData->getAction();
94
+ if (empty($action))
95
+ {
96
+ $this->log->error('Request type missing.');
97
+ $connectionData->setNullResponse();
98
+ return;
99
+ }
100
+
101
+ $httpHeaderFields = $this->prepareHttpHeaders($connectionData);
102
+ $parameters = $this->prepareParameters($connectionData);
103
+ $url = $this->prepareConnectionOptions(
104
+ $connectionData,
105
+ $httpHeaderFields,
106
+ $parameters
107
+ );
108
+
109
+ $response = $this->retrieveResponse($connectionData);
110
+
111
+ $connectionData->setResponse($response, $url);
112
+
113
+ $this->logResult($response);
114
+ }
115
+
116
+ private function prepareHttpHeaders($connectionData)
117
+ {
118
+ $httpHeaderFields = clone $connectionData->getHttpHeaderFields();
119
+
120
+ $language = $this->configuration->getLanguage();
121
+ if (!empty($language))
122
+ $httpHeaderFields['Accept-Language'] = $language;
123
+
124
+ return $httpHeaderFields;
125
+ }
126
+
127
+ private function prepareParameters($connectionData)
128
+ {
129
+ $parameters = clone $connectionData->getParameters();
130
+
131
+ if ($this->configuration->isDebugEnabled())
132
+ $parameters['verbose'] = 'true';
133
+
134
+ return $parameters;
135
+ }
136
+
137
+ private function prepareConnectionOptions(
138
+ $connectionData,
139
+ $httpHeaderFields,
140
+ $parameters
141
+ ) {
142
+ if ($this->configuration->isDebugEnabled()
143
+ && isset($_SERVER['HTTP_REFERER'])
144
+ && !$connectionData->issetConnectionOptions(CURLOPT_REFERER)
145
+ ) {
146
+ $connectionData->setConnectionOption(
147
+ CURLOPT_REFERER,
148
+ $_SERVER['HTTP_REFERER']
149
+ );
150
+ }
151
+
152
+ $connectionData->setConnectionOption(
153
+ CURLOPT_HTTPHEADER,
154
+ $httpHeaderFields->toHttpHeaderFields()
155
+ );
156
+
157
+ $url = $this->urlBuilder->getAuthenticationUrl(
158
+ $connectionData->getAction(),
159
+ $parameters
160
+ );
161
+
162
+ $connectionData->setConnectionOption(CURLOPT_URL, $url);
163
+
164
+ return $url;
165
+ }
166
+
167
+ private function retrieveResponse($connectionData)
168
+ {
169
+ $curlHandle = $this->curl->init();
170
+ if ($curlHandle === false)
171
+ {
172
+ $this->log->error("curl_init() did not return a handle for ID $id. "
173
+ . 'Setting an empty response...');
174
+ return FF::getInstance('Core\Server\NullResponse');
175
+ }
176
+
177
+ // We cannot use array_merge() here, because that does not preserve
178
+ // numeric keys. So we use array union instead. However, as opposed to
179
+ // array_merge(), the left-hand operator's keys will be preserved.
180
+ $curlOptions = $this->necessaryCurlOptions
181
+ + $connectionData->getConnectionOptions()
182
+ + $this->defaultCurlOptions;
183
+
184
+ $this->curl->setopt_array(
185
+ $curlHandle,
186
+ $curlOptions
187
+ );
188
+
189
+ $responseText = $this->curl->exec($curlHandle);
190
+ $httpCode = (int)$this->curl->getinfo($curlHandle, CURLINFO_HTTP_CODE);
191
+ $curlErrorNumber = $this->curl->errno($curlHandle);
192
+ $curlError = $this->curl->error($curlHandle);
193
+
194
+ $this->curl->close($curlHandle);
195
+
196
+ return FF::getInstance('Core\Server\Response',
197
+ $responseText,
198
+ $httpCode,
199
+ $curlErrorNumber,
200
+ $curlError
201
+ );
202
+ }
203
+
204
+ private function logResult($response)
205
+ {
206
+ $httpCode = $response->getHttpCode();
207
+ $curlError = $response->getConnectionError();
208
+ if ($httpCode >= 400) {
209
+ $this->log->error("Connection failed. HTTP code: $httpCode");
210
+ } else if ($httpCode == 0) {
211
+ $this->log->error("Connection refused. cURL error: $curlError");
212
+ } else if (floor($httpCode / 100) == 2) { // all successful status codes (2**)
213
+ $this->log->info("Request successful!");
214
+ }
215
+ }
216
+
217
+ private function hasUrlChanged($id)
218
+ {
219
+ $connectionData = $this->connectionData[$id];
220
+
221
+ if (FF::isInstanceOf($connectionData->getResponse(), 'Core\Server\NullResponse'))
222
+ return true;
223
+
224
+ $url = $this->urlBuilder->getNonAuthenticationUrl(
225
+ $connectionData->getAction(),
226
+ $this->prepareParameters($connectionData)
227
+ );
228
+ return $url != $connectionData->getPreviousUrl();
229
+ }
230
+ }
lib/FACTFinder/Core/Server/EasyCurlRequestFactory.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use \FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation backs the Request with an EasyCurlDataProvider.
8
+ */
9
+ class EasyCurlRequestFactory implements RequestFactoryInterface
10
+ {
11
+ /**
12
+ * @var \FACTFinder\Util\LoggerInterface
13
+ */
14
+ private $log;
15
+ private $loggerClass;
16
+
17
+ /**
18
+ * @var \FACTFinder\Core\ConfigurationInterface
19
+ */
20
+ protected $configuration;
21
+
22
+ /**
23
+ * @var EasyCurlDataProvider
24
+ */
25
+ private $dataProvider;
26
+
27
+ /**
28
+ * @var \FACTFinder\Util\Parameters
29
+ */
30
+ private $requestParameters;
31
+
32
+ /**
33
+ * @param string $loggerClass
34
+ * @param \FACTFinder\Core\ConfigurationInterface $configuration
35
+ * @param \FACTFinder\Util\Parameters $requestParameters
36
+ * @param \FACTFinder\Util\CurlInterface $curl Optional. If omitted, an
37
+ * instance of \FACTFinder\Util\Curl will be used.
38
+ */
39
+ public function __construct(
40
+ $loggerClass,
41
+ \FACTFinder\Core\ConfigurationInterface $configuration,
42
+ \FACTFinder\Util\Parameters $requestParameters,
43
+ \FACTFinder\Util\CurlInterface $curl = null
44
+ ) {
45
+ $this->loggerClass = $loggerClass;
46
+ $this->log = $loggerClass::getLogger(__CLASS__);
47
+ $this->configuration = $configuration;
48
+
49
+ $urlBuilder = FF::getInstance('Core\Server\UrlBuilder',
50
+ $loggerClass,
51
+ $configuration
52
+ );
53
+ $this->dataProvider = FF::getInstance('Core\Server\EasyCurlDataProvider',
54
+ $loggerClass,
55
+ $configuration,
56
+ is_null($curl) ? FF::getInstance('Util\Curl') : $curl,
57
+ $urlBuilder
58
+ );
59
+
60
+ $this->requestParameters = $requestParameters;
61
+ }
62
+
63
+ /**
64
+ * Returns a request object all wired up and ready for use.
65
+ * @return Request
66
+ */
67
+ public function getRequest()
68
+ {
69
+ $connectionData = FF::getInstance(
70
+ 'Core\Server\ConnectionData',
71
+ clone $this->requestParameters
72
+ );
73
+ return FF::getInstance('Core\Server\Request',
74
+ $this->loggerClass,
75
+ $connectionData,
76
+ $this->dataProvider
77
+ );
78
+ }
79
+ }
lib/FACTFinder/Core/Server/FileSystemDataProvider.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation retrieves the FACT-Finder data from the file system. File
8
+ * names are generated from request parameters. For the naming convention see
9
+ * the getFileName() method.
10
+ * Responses are queried sequentially and lazily and are cached as long as
11
+ * parameters don't change.
12
+ */
13
+ class FileSystemDataProvider extends AbstractDataProvider
14
+ {
15
+ /**
16
+ * @var \FACTFinder\Util\LoggerInterface
17
+ */
18
+ private $log;
19
+
20
+ /**
21
+ * @var string
22
+ */
23
+ protected $fileLocation;
24
+
25
+ public function __construct(
26
+ $loggerClass,
27
+ \FACTFinder\Core\ConfigurationInterface $configuration
28
+ ) {
29
+ parent::__construct($loggerClass, $configuration);
30
+
31
+ $this->log = $loggerClass::getLogger(__CLASS__);
32
+ }
33
+
34
+ public function setConnectTimeout($id, $timeout)
35
+ { }
36
+
37
+ public function setTimeout($id, $timeout)
38
+ { }
39
+
40
+ public function setFileLocation($path)
41
+ {
42
+ $this->fileLocation = ($path[strlen($path) -1] == DS) ? $path : $path . DS;
43
+ }
44
+
45
+ public function loadResponse($id)
46
+ {
47
+ if (!isset($this->connectionData[$id]))
48
+ throw new \InvalidArgumentException('Tried to get response for invalid ID $id.');
49
+
50
+
51
+ $connectionData = $this->connectionData[$id];
52
+
53
+ $action = $connectionData->getAction();
54
+ if (empty($action))
55
+ {
56
+ $this->log->error('Request type missing.');
57
+ $connectionData->setNullResponse();
58
+ return;
59
+ }
60
+
61
+ $fileName = $this->getFileName($connectionData);
62
+
63
+ if (!$this->hasFileNameChanged($id, $fileName))
64
+ return;
65
+
66
+ $this->log->info("Trying to load file: $fileName");
67
+
68
+ $response = FF::getInstance(
69
+ 'Core\Server\Response',
70
+ file_get_contents($fileName),
71
+ 200,
72
+ 0,
73
+ ''
74
+ );
75
+
76
+ $connectionData->setResponse($response, $fileName);
77
+ }
78
+
79
+ private function getFileName($connectionData)
80
+ {
81
+ $action = $connectionData->getAction();
82
+
83
+ // Replace the .ff file extension with an underscore.
84
+ $fileName = preg_replace('/[.]ff$/i', '_', $action);
85
+
86
+ $parameters = clone $connectionData->getParameters();
87
+
88
+ if (isset($parameters['format']))
89
+ $fileExtension = '.' . $parameters['format'];
90
+ else
91
+ $fileExtension = '.raw';
92
+
93
+ unset($parameters['format']);
94
+ unset($parameters['user']);
95
+ unset($parameters['pw']);
96
+ unset($parameters['timestamp']);
97
+ unset($parameters['channel']);
98
+
99
+ $rawParameters = &$parameters->getArray();
100
+
101
+ // We received that array by reference, so we can sort it to sort the
102
+ // Parameters object internally, too.
103
+ ksort($rawParameters, SORT_STRING);
104
+
105
+ $queryString = $parameters->toJavaQueryString();
106
+ $fileName .= str_replace('&', '_', $queryString);
107
+ $fileName .= $fileExtension;
108
+
109
+ return $this->fileLocation . $fileName;
110
+ }
111
+
112
+ private function hasFileNameChanged($id, $newFileName)
113
+ {
114
+ $connectionData = $this->connectionData[$id];
115
+
116
+ if (FF::isInstanceOf($connectionData->getResponse(), 'Core\Server\NullResponse'))
117
+ return true;
118
+
119
+ return $newFileName != $connectionData->getPreviousUrl();
120
+ }
121
+ }
lib/FACTFinder/Core/Server/FileSystemRequestFactory.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use \FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation backs the Request with a FileSystemDataProvider.
8
+ */
9
+ class FileSystemRequestFactory implements RequestFactoryInterface
10
+ {
11
+ /**
12
+ * @var \FACTFinder\Util\LoggerInterface
13
+ */
14
+ private $log;
15
+ private $loggerClass;
16
+
17
+ /**
18
+ * @var \FACTFinder\Core\ConfigurationInterface
19
+ */
20
+ protected $configuration;
21
+
22
+ /**
23
+ * @var FileSystemDataProvider
24
+ */
25
+ private $dataProvider;
26
+
27
+ /**
28
+ * @var \FACTFinder\Util\Parameters
29
+ */
30
+ private $requestParameters;
31
+
32
+ public function __construct(
33
+ $loggerClass,
34
+ \FACTFinder\Core\ConfigurationInterface $configuration,
35
+ \FACTFinder\Util\Parameters $requestParameters
36
+ ) {
37
+ $this->loggerClass = $loggerClass;
38
+ $this->log = $loggerClass::getLogger(__CLASS__);
39
+ $this->configuration = $configuration;
40
+
41
+ $this->dataProvider = FF::getInstance('Core\Server\FileSystemDataProvider',
42
+ $loggerClass,
43
+ $configuration
44
+ );
45
+
46
+ $this->requestParameters = $requestParameters;
47
+ }
48
+
49
+ public function setFileLocation($path)
50
+ {
51
+ $this->dataProvider->setFileLocation($path);
52
+ }
53
+
54
+ /**
55
+ * Returns a request object all wired up and ready for use.
56
+ * @return Request
57
+ */
58
+ public function getRequest()
59
+ {
60
+ $connectionData = FF::getInstance(
61
+ 'Core\Server\ConnectionData',
62
+ clone $this->requestParameters
63
+ );
64
+ return FF::getInstance('Core\Server\Request',
65
+ $this->loggerClass,
66
+ $connectionData,
67
+ $this->dataProvider
68
+ );
69
+ }
70
+ }
lib/FACTFinder/Core/Server/MultiCurlDataProvider.php ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation retrieves the FACT-Finder data by using the cURL's "multi
8
+ * interface".
9
+ * Responses are queried in parallel and lazily and are cached as long as
10
+ * parameters don't change.
11
+ */
12
+ class MultiCurlDataProvider extends AbstractDataProvider
13
+ {
14
+ /**
15
+ * @var \FACTFinder\Util\LoggerInterface
16
+ */
17
+ private $log;
18
+
19
+ /**
20
+ * @var UrlBuilder
21
+ */
22
+ protected $urlBuilder;
23
+
24
+ /**
25
+ * @var \FACTFinder\Util\CurlInterface
26
+ */
27
+ protected $curl;
28
+
29
+ protected $defaultCurlOptions;
30
+ protected $necessaryCurlOptions;
31
+
32
+ /**
33
+ * @var bool
34
+ * This is used to issue a warning if not all connections are being fetched
35
+ * at the same time.
36
+ */
37
+ protected $usedBefore;
38
+
39
+ public function __construct(
40
+ $loggerClass,
41
+ \FACTFinder\Core\ConfigurationInterface $configuration,
42
+ \FACTFinder\Util\CurlInterface $curl,
43
+ UrlBuilder $urlBuilder
44
+ ) {
45
+ parent::__construct($loggerClass, $configuration);
46
+
47
+ $this->log = $loggerClass::getLogger(__CLASS__);
48
+
49
+ $this->urlBuilder = $urlBuilder;
50
+
51
+ $this->curl = $curl;
52
+
53
+ $this->defaultCurlOptions = array(
54
+ CURLOPT_CONNECTTIMEOUT => $this->configuration->getDefaultConnectTimeout(),
55
+ CURLOPT_TIMEOUT => $this->configuration->getDefaultTimeout(),
56
+ CURLOPT_SSL_VERIFYPEER => false,
57
+ CURLOPT_SSL_VERIFYHOST => false,
58
+ CURLOPT_ENCODING => '',
59
+ );
60
+
61
+ $this->necessaryCurlOptions = array(
62
+ CURLOPT_RETURNTRANSFER => true,
63
+ );
64
+ }
65
+
66
+ public function setConnectTimeout($id, $timeout)
67
+ {
68
+ if (!isset($this->connectionData[$id]))
69
+ throw new \InvalidArgumentException('Tried to set timeout for invalid ID $id.');
70
+
71
+ $this->connectionData[$id]->setConnectionOption(
72
+ CURLOPT_CONNECTTIMEOUT,
73
+ $timeout
74
+ );
75
+ }
76
+
77
+ public function setTimeout($id, $timeout)
78
+ {
79
+ if (!isset($this->connectionData[$id]))
80
+ throw new \InvalidArgumentException('Tried to set timeout for invalid ID $id.');
81
+
82
+ $this->connectionData[$id]->setConnectionOption(
83
+ CURLOPT_TIMEOUT,
84
+ $timeout
85
+ );
86
+ }
87
+
88
+ // TODO: Could this be refactored some more?
89
+ public function loadResponse($id)
90
+ {
91
+ if (!isset($this->connectionData[$id]))
92
+ throw new \InvalidArgumentException('Tried to get response for invalid ID $id.');
93
+
94
+ // Although this implementation of the data provider generally loads all
95
+ // all available responses at once (basically ignoring the $id
96
+ // parameter), it will not do so if the requested $id does not actually
97
+ // need a connection itself. This allows for other connections to be
98
+ // deferred as long as possible.
99
+ if (!$this->hasUrlChanged($id))
100
+ return;
101
+
102
+ $connectionData = $this->connectionData[$id];
103
+
104
+ $action = $connectionData->getAction();
105
+ if (empty($action))
106
+ {
107
+ $this->log->error('Request type missing.');
108
+ $connectionData->setNullResponse();
109
+ return;
110
+ }
111
+
112
+ // From now on we ignore what parameter has been passed in and just load
113
+ // all available responses.
114
+ $connectionsToFetch = array();
115
+ foreach ($this->connectionData as $id => $connectionData)
116
+ {
117
+ $action = $connectionData->getAction();
118
+ if (!$this->hasUrlChanged($id)
119
+ || empty($action)
120
+ ) {
121
+ continue;
122
+ }
123
+
124
+ $httpHeaderFields = $this->prepareHttpHeaders($connectionData);
125
+ $parameters = $this->prepareParameters($connectionData);
126
+ $url = $this->prepareConnectionOptions(
127
+ $connectionData,
128
+ $httpHeaderFields,
129
+ $parameters
130
+ );
131
+
132
+ $connectionsToFetch[$id] = array(
133
+ 'connection' => $connectionData,
134
+ 'url' => $url
135
+ );
136
+ }
137
+
138
+ if (count($connectionsToFetch))
139
+ {
140
+ if ($this->usedBefore)
141
+ $this->log->warn('loadResponse() has been called before. You should try to configure all requests '
142
+ . 'before loading the first response so that all connections can be made in parallel.');
143
+
144
+ $this->retrieveResponses($connectionsToFetch);
145
+
146
+ $this->usedBefore = true;
147
+ }
148
+ }
149
+
150
+ private function prepareHttpHeaders($connectionData)
151
+ {
152
+ $httpHeaderFields = clone $connectionData->getHttpHeaderFields();
153
+
154
+ $language = $this->configuration->getLanguage();
155
+ if (!empty($language))
156
+ $httpHeaderFields['Accept-Language'] = $language;
157
+
158
+ return $httpHeaderFields;
159
+ }
160
+
161
+ private function prepareParameters($connectionData)
162
+ {
163
+ $parameters = clone $connectionData->getParameters();
164
+
165
+ if ($this->configuration->isDebugEnabled())
166
+ $parameters['verbose'] = 'true';
167
+
168
+ return $parameters;
169
+ }
170
+
171
+ private function prepareConnectionOptions(
172
+ $connectionData,
173
+ $httpHeaderFields,
174
+ $parameters
175
+ ) {
176
+ if ($this->configuration->isDebugEnabled()
177
+ && isset($_SERVER['HTTP_REFERER'])
178
+ && !$connectionData->issetConnectionOption(CURLOPT_REFERER)
179
+ ) {
180
+ $connectionData->setConnectionOption(
181
+ CURLOPT_REFERER,
182
+ $_SERVER['HTTP_REFERER']
183
+ );
184
+ }
185
+
186
+ $connectionData->setConnectionOption(
187
+ CURLOPT_HTTPHEADER,
188
+ $httpHeaderFields->toHttpHeaderFields()
189
+ );
190
+
191
+ $url = $this->urlBuilder->getAuthenticationUrl(
192
+ $connectionData->getAction(),
193
+ $parameters
194
+ );
195
+
196
+ $connectionData->setConnectionOption(CURLOPT_URL, $url);
197
+
198
+ // Return non-authentication URL for reproducability.
199
+ return $this->urlBuilder->getNonAuthenticationUrl(
200
+ $connectionData->getAction(),
201
+ $parameters
202
+ );
203
+ }
204
+
205
+ private function retrieveResponses($connectionsToFetch)
206
+ {
207
+ $curl = $this->curl;
208
+
209
+ $multiHandle = $curl->multi_init();
210
+ if ($multiHandle === false)
211
+ {
212
+ $this->log->error("curl_multi_init() did not return a multi handle. "
213
+ . 'Setting a empty responses...');
214
+ foreach ($connectionsToFetch as $id => $data)
215
+ {
216
+ $data['connection']->setResponse(
217
+ FF::getInstance('Core\Server\NullResponse'),
218
+ $data['url']
219
+ );
220
+ }
221
+ }
222
+
223
+ // Use a reference so that we can add a 'handle' field in the loop.
224
+ foreach ($connectionsToFetch as $id => &$data)
225
+ {
226
+ $data['handle'] = $curl->init();
227
+
228
+ if ($data['handle'] === false)
229
+ {
230
+ $this->log->error("curl_init() did not return a handle for ID $id. "
231
+ . 'Setting an empty response...');
232
+ $data['connection']->setResponse(
233
+ FF::getInstance('Core\Server\NullResponse'),
234
+ $data['url']
235
+ );
236
+ }
237
+
238
+ // We cannot use array_merge() here, because that does not preserve
239
+ // numeric keys. So we use array union instead. However, as opposed
240
+ // to array_merge() the left-hand operator's keys will be preserved.
241
+ $curlOptions = $this->necessaryCurlOptions
242
+ + $data['connection']->getConnectionOptions()
243
+ + $this->defaultCurlOptions;
244
+
245
+ $curl->setopt_array(
246
+ $data['handle'],
247
+ $curlOptions
248
+ );
249
+
250
+ $curl->multi_add_handle($multiHandle, $data['handle']);
251
+ }
252
+ unset($data); // Otherwise the reference remains and reusing the
253
+ // variable name $data further down this function will
254
+ // change the last element of the array.
255
+
256
+ do
257
+ {
258
+ $status = $curl->multi_exec($multiHandle, $still_running);
259
+ } while ($status == CURLM_CALL_MULTI_PERFORM);
260
+
261
+ while ($still_running && $status == CURLM_OK)
262
+ {
263
+ // curl_multi_select sometimes returns -1 indefinitely in which case
264
+ // the usual curl multi loop would run endlessly. This is due to the
265
+ // underlying cURL library in C, which returns -1 upon errors which
266
+ // cannot be checked from the outside. Simply waiting for 100 ms is
267
+ // the suggested workaround. For further information see:
268
+ // https://bugs.php.net/bug.php?id=61141
269
+ // https://bugs.php.net/bug.php?id=63411
270
+ // https://bugs.php.net/bug.php?id=63842
271
+ // http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
272
+ if ($curl->multi_select($multiHandle) == -1)
273
+ usleep(100);
274
+
275
+ do
276
+ {
277
+ $status = $curl->multi_exec($multiHandle, $still_running);
278
+ } while ($status == CURLM_CALL_MULTI_PERFORM);
279
+
280
+ // TODO: Fetch responses within this loop as they are ready (while
281
+ // the others are still loading).
282
+ }
283
+
284
+ if ($status != CURLM_OK)
285
+ $this->log->error('There was a cURL error: ' . $status);
286
+
287
+ while (($msg = $curl->multi_info_read($multiHandle)) !== false)
288
+ {
289
+ // We do not check the value of $msg['msg'], because currently this
290
+ // will always be CURLMSG_DONE.
291
+ $curlErrorNumber = $msg['result'];
292
+
293
+ // Set $data to the data array corresponding to the current handle.
294
+ foreach ($connectionsToFetch as $data)
295
+ if ($data['handle'] === $msg['handle'])
296
+ break;
297
+
298
+ // We could skip multi_getcontent if $curlErrorNumber is different
299
+ // from CURLE_OK, as it will always return null.
300
+ $responseText = $curl->multi_getcontent($data['handle']);
301
+ $httpCode = (int)$curl->getinfo($data['handle'], CURLINFO_HTTP_CODE);
302
+ $curlError = $curl->error($data['handle']);
303
+
304
+ $curl->multi_remove_handle($multiHandle, $data['handle']);
305
+ $this->curl->close($data['handle']);
306
+
307
+ $response = FF::getInstance('Core\Server\Response',
308
+ $responseText,
309
+ $httpCode,
310
+ $curlErrorNumber,
311
+ $curlError
312
+ );
313
+
314
+ $data['connection']->setResponse($response, $data['url']);
315
+ $this->logResult($response);
316
+ }
317
+ }
318
+
319
+ private function logResult($response)
320
+ {
321
+ $httpCode = $response->getHttpCode();
322
+ $curlError = $response->getConnectionError();
323
+ if ($httpCode >= 400) {
324
+ $this->log->error("Connection failed. HTTP code: $httpCode");
325
+ } else if ($httpCode == 0) {
326
+ $this->log->error("Connection refused. cURL error: $curlError");
327
+ } else if (floor($httpCode / 100) == 2) { // all successful status codes (2**)
328
+ $this->log->info("Request successful!");
329
+ }
330
+ }
331
+
332
+ private function hasUrlChanged($id)
333
+ {
334
+ $connectionData = $this->connectionData[$id];
335
+
336
+ if (FF::isInstanceOf($connectionData->getResponse(), 'Core\Server\NullResponse'))
337
+ return true;
338
+
339
+ $url = $this->urlBuilder->getNonAuthenticationUrl(
340
+ $connectionData->getAction(),
341
+ $this->prepareParameters($connectionData)
342
+ );
343
+
344
+ return $url != $connectionData->getPreviousUrl();
345
+ }
346
+ }
lib/FACTFinder/Core/Server/MultiCurlRequestFactory.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use \FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * This implementation backs the Request with a MultiCurlDataProvider.
8
+ */
9
+ class MultiCurlRequestFactory implements RequestFactoryInterface
10
+ {
11
+ /**
12
+ * @var \FACTFinder\Util\LoggerInterface
13
+ */
14
+ private $log;
15
+ private $loggerClass;
16
+
17
+ /**
18
+ * @var \FACTFinder\Core\ConfigurationInterface
19
+ */
20
+ protected $configuration;
21
+
22
+ /**
23
+ * @var MultiCurlDataProvider
24
+ */
25
+ private $dataProvider;
26
+
27
+ /**
28
+ * @var \FACTFinder\Util\Parameters
29
+ */
30
+ private $requestParameters;
31
+
32
+ /**
33
+ * @param string $loggerClass
34
+ * @param \FACTFinder\Core\ConfigurationInterface $configuration
35
+ * @param \FACTFinder\Util\Parameters $requestParameters
36
+ * @param \FACTFinder\Util\CurlInterface $curl Optional. If omitted, an
37
+ * instance of \FACTFinder\Util\Curl will be used.
38
+ */
39
+ public function __construct(
40
+ $loggerClass,
41
+ \FACTFinder\Core\ConfigurationInterface $configuration,
42
+ \FACTFinder\Util\Parameters $requestParameters,
43
+ \FACTFinder\Util\CurlInterface $curl = null
44
+ ) {
45
+ $this->loggerClass = $loggerClass;
46
+ $this->log = $loggerClass::getLogger(__CLASS__);
47
+ $this->configuration = $configuration;
48
+
49
+ $urlBuilder = FF::getInstance('Core\Server\UrlBuilder',
50
+ $loggerClass,
51
+ $configuration
52
+ );
53
+ $this->dataProvider = FF::getInstance('Core\Server\MultiCurlDataProvider',
54
+ $loggerClass,
55
+ $configuration,
56
+ is_null($curl) ? FF::getInstance('Util\Curl') : $curl,
57
+ $urlBuilder
58
+ );
59
+
60
+ $this->requestParameters = $requestParameters;
61
+ }
62
+
63
+ /**
64
+ * Returns a request object all wired up and ready for use.
65
+ * @return Request
66
+ */
67
+ public function getRequest()
68
+ {
69
+ $connectionData = FF::getInstance(
70
+ 'Core\Server\ConnectionData',
71
+ clone $this->requestParameters
72
+ );
73
+ return FF::getInstance('Core\Server\Request',
74
+ $this->loggerClass,
75
+ $connectionData,
76
+ $this->dataProvider
77
+ );
78
+ }
79
+ }
lib/FACTFinder/Core/Server/NullResponse.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ /**
5
+ * Null Object implementation of the Response class, e.g. to be used if
6
+ * no response could be obtained.
7
+ */
8
+ class NullResponse extends Response
9
+ {
10
+ public function __construct() {}
11
+
12
+ public function getContent() { return ''; }
13
+ public function getHttpCode() { return 0; }
14
+ public function getConnectionErrorNumber() { return 0; }
15
+ public function getConnectionError() { return ''; }
16
+ }
lib/FACTFinder/Core/Server/Request.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ /**
5
+ * This is basically a Facade for ConnectionData and DataProviders, allowing
6
+ * access only to parameters, HTTP header fields, the target action a few
7
+ * selected connection options, plus retrieval of the response. ConnectionData
8
+ * and DataProvider are hidden behind this class and should not be used by
9
+ * anyone except Requests and their factories.
10
+ */
11
+ class Request
12
+ {
13
+ /**
14
+ * @var \FACTFinder\Util\LoggerInterface
15
+ */
16
+ private $log;
17
+
18
+ /**
19
+ * @var int
20
+ */
21
+ private $id;
22
+
23
+ /**
24
+ * @var ConnectionData
25
+ */
26
+ private $connectionData;
27
+
28
+ /**
29
+ * @var ConnectionData
30
+ */
31
+ protected $blLoaded;
32
+
33
+ /**
34
+ * @var AbstractDataProvider
35
+ */
36
+ private $dataProvider;
37
+
38
+ public function __construct(
39
+ $loggerClass,
40
+ ConnectionData $connectionData,
41
+ AbstractDataProvider $dataProvider
42
+ ) {
43
+ $this->log = $loggerClass::getLogger(__CLASS__);
44
+
45
+ $this->id = $dataProvider->register($connectionData);
46
+
47
+ $this->connectionData = $connectionData;
48
+ $this->dataProvider = $dataProvider;
49
+ $this->blLoaded = false;
50
+ }
51
+
52
+ public function __destruct()
53
+ {
54
+ $this->dataProvider->unregister($this->id);
55
+ }
56
+
57
+ /**
58
+ * Returns the parameters object used for the request, on which HTTP header
59
+ * fields can be changed.
60
+ *
61
+ * @return \FACTFinder\Util\Parameters
62
+ */
63
+ public function getHttpHeaderFields()
64
+ {
65
+ return $this->connectionData->getHttpHeaderFields();
66
+ }
67
+
68
+ /**
69
+ * Returns the parameters object used for the request, on which parameters
70
+ * can be changed.
71
+ *
72
+ * @return \FACTFinder\Util\Parameters
73
+ */
74
+ public function getParameters()
75
+ {
76
+ return $this->connectionData->getParameters();
77
+ }
78
+
79
+ /**
80
+ * Set the action to be queried on the FACT-Finder server. e.g. "Search.ff".
81
+ *
82
+ * @param string $action
83
+ */
84
+ public function setAction($action)
85
+ {
86
+ $this->connectionData->setAction($action);
87
+ }
88
+
89
+ /**
90
+ * @param int $timeout
91
+ */
92
+ public function setConnectTimeout($timeout)
93
+ {
94
+ $this->dataProvider->setConnectTimeout($this->id, $timeout);
95
+ }
96
+
97
+ /**
98
+ * @param int $timeout
99
+ */
100
+ public function setTimeout($timeout)
101
+ {
102
+ $this->dataProvider->setTimeout($this->id, $timeout);
103
+ }
104
+
105
+ /**
106
+ * @return Response
107
+ */
108
+ public function getResponse()
109
+ {
110
+ if(!$this->blLoaded) {
111
+ $this->dataProvider->loadResponse($this->id);
112
+ $this->blLoaded = true;
113
+ }
114
+ return $this->connectionData->getResponse();
115
+ }
116
+
117
+ /**
118
+ * Reset loaded state of request to force reloading from server.
119
+ *
120
+ * @return void
121
+ */
122
+ public function resetLoaded()
123
+ {
124
+ $this->blLoaded = false;
125
+ }
126
+ }
lib/FACTFinder/Core/Server/RequestFactoryInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ /**
5
+ * Use this to obtain Request objects instead of creating them directly.
6
+ */
7
+ interface RequestFactoryInterface
8
+ {
9
+ /**
10
+ * Returns a request object all wired up and ready for use.
11
+ * @return Request
12
+ */
13
+ public function getRequest();
14
+ }
lib/FACTFinder/Core/Server/Response.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ /**
5
+ * Represents a request response from the FACT-Finder server.
6
+ */
7
+ class Response
8
+ {
9
+ /**
10
+ * @var string
11
+ */
12
+ private $content;
13
+
14
+ /**
15
+ * @var int
16
+ */
17
+ private $httpCode;
18
+
19
+ /**
20
+ * @var int
21
+ */
22
+ private $connectionErrorCode;
23
+
24
+ /**
25
+ * @var string
26
+ */
27
+ private $connectionError;
28
+
29
+ public function __construct(
30
+ $content,
31
+ $httpCode,
32
+ $connectionErrorCode,
33
+ $connectionError
34
+ ) {
35
+ $this->content = $content;
36
+ $this->httpCode = $httpCode;
37
+ $this->connectionErrorCode = $connectionErrorCode;
38
+ $this->connectionError = $connectionError;
39
+ }
40
+
41
+ /**
42
+ * @return string
43
+ */
44
+ public function getContent()
45
+ {
46
+ return $this->content;
47
+ }
48
+
49
+ /**
50
+ * @return int
51
+ */
52
+ public function getHttpCode()
53
+ {
54
+ return $this->httpCode;
55
+ }
56
+
57
+ /**
58
+ * @return int
59
+ */
60
+ public function getConnectionErrorCode()
61
+ {
62
+ return $this->connectionErrorCode;
63
+ }
64
+
65
+ /**
66
+ * @return string
67
+ */
68
+ public function getConnectionError()
69
+ {
70
+ return $this->connectionError;
71
+ }
72
+ }
lib/FACTFinder/Core/Server/UrlBuilder.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core\Server;
3
+
4
+ use FACTFinder\Loader as FF;
5
+
6
+ /**
7
+ * Assembles URLs to the FACT-Finder server for different kinds of
8
+ * authentication based on the given parameters and the configuration.
9
+ */
10
+ class UrlBuilder
11
+ {
12
+ /**
13
+ * @var FACTFinder\Util\LoggerInterface
14
+ */
15
+ private $log;
16
+
17
+ /**
18
+ * @var ConfigurationInterface
19
+ */
20
+ protected $configuration;
21
+
22
+
23
+ /**
24
+ * @param string $loggerClass Class name of logger to use. The class should
25
+ * implement FACTFinder\Util\LoggerInterface.
26
+ * @param ConfigurationInterface $configuration
27
+ * @param FACTFinder\Util\Parameters $parameters Optional parameters object
28
+ * to initialize the UrlBuilder with.
29
+ */
30
+ public function __construct(
31
+ $loggerClass,
32
+ \FACTFinder\Core\ConfigurationInterface $configuration
33
+ ) {
34
+ $this->log = $loggerClass::getLogger(__CLASS__);
35
+ $this->log->info("Initializing URL Builder.");
36
+
37
+ $this->configuration = $configuration;
38
+ }
39
+
40
+ /**
41
+ * Get URL without authentication data.
42
+ * Note that this method may set a channel parameter if there is none
43
+ * already.
44
+ *
45
+ * @param string $action The action to be targeted on the FACT-Finder
46
+ * server.
47
+ * @param FACTFinder\Util\Parameters $parameters The parameters object from
48
+ * which to build the URL.
49
+ *
50
+ * @return string The full URL.
51
+ */
52
+ public function getNonAuthenticationUrl(
53
+ $action,
54
+ \FACTFinder\Util\Parameters $parameters
55
+ ) {
56
+ $configuration = $this->configuration;
57
+
58
+ $this->ensureChannelParameter($parameters);
59
+
60
+ $url = $this->buildAddress($action)
61
+ . (count($parameters) ? '?' : '') . $parameters->toJavaQueryString();
62
+
63
+ return $url;
64
+ }
65
+
66
+ /**
67
+ * Returns a full URL with authentication data. The type of authentication
68
+ * is determined from the configuration.
69
+ * Note that this method may set a channel parameter if there is none
70
+ * already.
71
+ *
72
+ * @param string $action The action to be targeted on the FACT-Finder
73
+ * server.
74
+ * @param FACTFinder\Util\Parameters $parameters The parameters object from
75
+ * which to build the URL.
76
+ *
77
+ * @return string The full URL.
78
+ *
79
+ * @throws Exception if no valid authentication type was configured.
80
+ */
81
+ public function getAuthenticationUrl(
82
+ $action,
83
+ \FACTFinder\Util\Parameters $parameters
84
+ ) {
85
+ $this->ensureChannelParameter($parameters);
86
+
87
+ $c = $this->configuration;
88
+ if ($c->isAdvancedAuthenticationType())
89
+ return $this->getAdvancedAuthenticationUrl($action, $parameters);
90
+ else if ($c->isSimpleAuthenticationType())
91
+ return $this->getSimpleAuthenticationUrl($action, $parameters);
92
+ else if ($c->isHttpAuthenticationType())
93
+ return $this->getHttpAuthenticationUrl($action, $parameters);
94
+ else
95
+ throw new \Exception('Invalid authentication type configured.');
96
+ }
97
+
98
+ /**
99
+ * Get URL with advanced authentication encryption.
100
+ *
101
+ * @param string $action The action to be targeted on the FACT-Finder
102
+ * server.
103
+ * @param FACTFinder\Util\Parameters $parameters The parameters object from
104
+ * which to build the URL.
105
+ *
106
+ * @return string The full URL.
107
+ */
108
+ protected function getAdvancedAuthenticationUrl(
109
+ $action,
110
+ \FACTFinder\Util\Parameters $parameters
111
+ ) {
112
+ $configuration = $this->configuration;
113
+
114
+ $ts = time() . '000'; //milliseconds needed
115
+ $prefix = $configuration->getAuthenticationPrefix();
116
+ $postfix = $configuration->getAuthenticationPostfix();
117
+ $hashedPW = md5($prefix
118
+ . $ts
119
+ . md5($configuration->getPassword())
120
+ . $postfix);
121
+ $authenticationParameters = 'timestamp=' . $ts
122
+ . '&username=' . $configuration->getUserName()
123
+ . '&password=' . $hashedPW;
124
+
125
+ $url = $this->buildAddress($action)
126
+ . '?' . $parameters->toJavaQueryString()
127
+ . (count($parameters) ? '&' : '') . $authenticationParameters;
128
+
129
+ $this->log->info("Request Url: " . $url);
130
+ return $url;
131
+ }
132
+
133
+ /**
134
+ * Get URL with simple authentication encryption.
135
+ *
136
+ * @param string $action The action to be targeted on the FACT-Finder
137
+ * server.
138
+ * @param FACTFinder\Util\Parameters $parameters The parameters object from
139
+ * which to build the URL.
140
+ *
141
+ * @return string The full URL.
142
+ */
143
+ protected function getSimpleAuthenticationUrl(
144
+ $action,
145
+ \FACTFinder\Util\Parameters $parameters
146
+ ) {
147
+ $configuration = $this->configuration;
148
+
149
+ $ts = time() . '000'; //milliseconds needed but won't be considered
150
+ $authenticationParameters = "timestamp=" . $ts
151
+ . '&username=' . $configuration->getUserName()
152
+ . '&password=' . md5($configuration->getPassword());
153
+
154
+ $url = $this->buildAddress($action)
155
+ . '?' . $parameters->toJavaQueryString()
156
+ . (count($parameters) ? '&' : '') . $authenticationParameters;
157
+
158
+ $this->log->info("Request Url: " . $url);
159
+ return $url;
160
+ }
161
+
162
+ /**
163
+ * Get URL with HTTP authentication.
164
+ *
165
+ * @param string $action The action to be targeted on the FACT-Finder
166
+ * server.
167
+ * @param FACTFinder\Util\Parameters $parameters The parameters object from
168
+ * which to build the URL.
169
+ *
170
+ * @return string The full URL.
171
+ */
172
+ protected function getHttpAuthenticationUrl(
173
+ $action,
174
+ \FACTFinder\Util\Parameters $parameters
175
+ ) {
176
+ $configuration = $this->configuration;
177
+
178
+ $authentication = sprintf(
179
+ '%s:%s@',
180
+ $configuration->getUserName(),
181
+ $configuration->getPassword()
182
+ );
183
+ if ($authentication == ':@') $authentication = '';
184
+
185
+ $url = $this->buildAddress($action, true)
186
+ . (count($parameters) ? '?' : '') . $parameters->toJavaQueryString();
187
+
188
+ $this->log->info("Request Url: " . $url);
189
+ return $url;
190
+ }
191
+
192
+ /**
193
+ * If no channel is set, try to fill it from configuration data.
194
+ *
195
+ * @param FACTFinder\Util\Parameters $parameters The parameters object to
196
+ * check.
197
+ */
198
+ protected function ensureChannelParameter($parameters) {
199
+ if ((!isset($parameters['channel'])
200
+ || $parameters['channel'] == '')
201
+ && $this->configuration->getChannel() != ''
202
+ ) {
203
+ $parameters['channel'] = $this->configuration->getChannel();
204
+ }
205
+ }
206
+
207
+ protected function buildAddress($action, $includeHttpAuthentication = false)
208
+ {
209
+ $configuration = $this->configuration;
210
+
211
+ $authentication = '';
212
+ if ($includeHttpAuthentication
213
+ && $configuration->getUserName() != ''
214
+ && $configuration->getPassword() != ''
215
+ ) {
216
+ $authentication = sprintf(
217
+ '%s:%s@',
218
+ $configuration->getUserName(),
219
+ $configuration->getPassword()
220
+ );
221
+ }
222
+
223
+ return $configuration->getRequestProtocol() . '://'
224
+ . $authentication . $configuration->getServerAddress()
225
+ . ':' . $configuration->getServerPort()
226
+ . '/' . $configuration->getContext()
227
+ . '/' . $action;
228
+ }
229
+ }
lib/FACTFinder/Core/Utf8EncodingConverter.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Implements the AbstractEncodingConverter using utf8_encode() and
6
+ * utf_decode().
7
+ */
8
+ class Utf8EncodingConverter extends AbstractEncodingConverter
9
+ {
10
+ function __construct(
11
+ $loggerClass,
12
+ ConfigurationInterface $configuration
13
+ ) {
14
+ parent::__construct($loggerClass, $configuration);
15
+ $this->log = $loggerClass::getLogger(__CLASS__);
16
+ }
17
+
18
+ protected function convertString($inCharset, $outCharset, $string)
19
+ {
20
+ if (strtolower($inCharset) != strtolower($outCharset)
21
+ && !empty($inCharset)
22
+ && !empty($outCharset)
23
+ ) {
24
+ if (strtolower($inCharset) == 'utf-8')
25
+ {
26
+ if (strtolower($outCharset) != 'iso-8859-1')
27
+ $this->log->warn(
28
+ "utf8_decode() does not support $outCharset. If $outCharset is not compatible with ISO-8859-1, "
29
+ . "the resulting string may contain wrong or invalid characters."
30
+ );
31
+ $string = utf8_decode($string);
32
+ }
33
+ else if (strtolower($outCharset) == 'utf-8')
34
+ {
35
+ if (strtolower($inCharset) != 'iso-8859-1')
36
+ $this->log->warn(
37
+ "utf8_encode() does not support $inCharset. If $inCharset is not compatible with ISO-8859-1, "
38
+ . "the resulting string may contain wrong characters."
39
+ );
40
+ $string = utf8_encode($string);
41
+ }
42
+ else
43
+ {
44
+ $this->log->error("Conversion between non-UTF-8 encodings not possible.");
45
+ throw new \InvalidArgumentException("Cannot handle conversion from $inCharset to $outCharset!");
46
+ }
47
+ }
48
+ return $string;
49
+ }
50
+ }
lib/FACTFinder/Core/XmlConfiguration.php ADDED
@@ -0,0 +1,349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FACTFinder\Core;
3
+
4
+ /**
5
+ * Implements ConfigurationInterface by reading from an XML file. Also allows
6
+ * for some values to be changed later on.
7
+ */
8
+ class XmlConfiguration extends AbstractConfiguration
9
+ {
10
+ const HTTP_AUTHENTICATION = 'http';
11
+ const SIMPLE_AUTHENTICATION = 'simple';
12
+ const ADVANCED_AUTHENTICATION = 'advanced';
13
+
14
+ /**
15
+ * @var SimpleXMLElement XML representation of the configuration.
16
+ */
17
+ private $configuration;
18
+
19
+ private $authenticationType = null;
20
+
21
+ private $clientMappings;
22
+ private $serverMappings;
23
+ private $ignoredClientParameters;
24
+ private $ignoredServerParameters;
25
+ private $whitelistClientParameters;
26
+ private $whitelistServerParameters;
27
+ private $requiredClientParameters;
28
+ private $requiredServerParameters;
29
+
30
+ private $pageContentEncoding = null;
31
+ private $clientUrlEncoding = null;
32
+
33
+ /**
34
+ * Create a new configuration from an XML file. The outer element in the XML
35
+ * tree must be named <configuration>. The actual data is read from a child
36
+ * of this element whose name can be specified through the second argument.
37
+ * @param string $fileName Name of configuration file.
38
+ * @param type $element Name of the XML element from which to read
39
+ * configuration data.
40
+ * @return XmlConfiguration
41
+ */
42
+ public function __construct($fileName, $element)
43
+ {
44
+ libxml_use_internal_errors(true);
45
+ $xmlData = new \SimpleXMLElement($fileName, 0, true);
46
+ if (!isset($xmlData->$element))
47
+ throw new \Exception("Specified configuration file does not contain section $element");
48
+ $this->configuration = $xmlData->$element;
49
+ }
50
+
51
+ public function isDebugEnabled()
52
+ {
53
+ return (string)$this->configuration->debug == 'true';
54
+ }
55
+
56
+ public function getCustomValue($name)
57
+ {
58
+ return (string)$this->configuration->$name;
59
+ }
60
+
61
+ public function getRequestProtocol()
62
+ {
63
+ return (string)$this->configuration->connection->protocol;
64
+ }
65
+
66
+ public function getServerAddress()
67
+ {
68
+ return (string)$this->configuration->connection->address;
69
+ }
70
+
71
+ public function getServerPort()
72
+ {
73
+ return (int)$this->configuration->connection->port;
74
+ }
75
+
76
+ public function getContext()
77
+ {
78
+ return (string)$this->configuration->connection->context;
79
+ }
80
+
81
+ public function getChannel()
82
+ {
83
+ return (string)$this->configuration->connection->channel;
84
+ }
85
+
86
+ public function getLanguage()
87
+ {
88
+ return (string)$this->configuration->connection->language;
89
+ }
90
+
91
+ public function isHttpAuthenticationType()
92
+ {
93
+ return $this->retrieveAuthenticationType() == self::HTTP_AUTHENTICATION;
94
+ }
95
+
96
+ public function isSimpleAuthenticationType()
97
+ {
98
+ return $this->retrieveAuthenticationType() == self::SIMPLE_AUTHENTICATION;
99
+ }
100
+
101
+ public function isAdvancedAuthenticationType()
102
+ {
103
+ return $this->retrieveAuthenticationType() == self::ADVANCED_AUTHENTICATION;
104
+ }
105
+
106
+ private function retrieveAuthenticationType()
107
+ {
108
+ if (is_null($this->authenticationType))
109
+ $this->authenticationType = (string)$this->configuration
110
+ ->connection
111
+ ->authentication
112
+ ->type;
113
+ return strtolower($this->authenticationType);
114
+ }
115
+
116
+ public function makeHttpAuthenticationType()
117
+ {
118
+ $this->authenticationType = self::HTTP_AUTHENTICATION;
119
+ }
120
+
121
+ public function makeSimpleAuthenticationType()
122
+ {
123
+ $this->authenticationType = self::SIMPLE_AUTHENTICATION;
124
+ }
125
+
126
+ public function makeAdvancedAuthenticationType()
127
+ {
128
+ $this->authenticationType = self::ADVANCED_AUTHENTICATION;
129
+ }
130
+
131
+ public function getUserName()
132
+ {
133
+ return (string)$this->configuration->connection->authentication->username;
134
+ }
135
+
136
+ public function getPassword()
137
+ {
138
+ return (string)$this->configuration->connection->authentication->password;
139
+ }
140
+
141
+ public function getAuthenticationPrefix()
142
+ {
143
+ return (string)$this->configuration->connection->authentication->prefix;
144
+ }
145
+
146
+ public function getAuthenticationPostfix()
147
+ {
148
+ return (string)$this->configuration->connection->authentication->postfix;
149
+ }
150
+
151
+ public function getClientMappings()
152
+ {
153
+ if ($this->clientMappings == null) {
154
+ $this->clientMappings = $this->retrieveMappings(
155
+ $this->configuration->parameters->client
156
+ );
157
+ }
158
+ return $this->clientMappings;
159
+ }
160
+
161
+ public function getServerMappings()
162
+ {
163
+ if ($this->serverMappings == null) {
164
+ $this->serverMappings = $this->retrieveMappings(
165
+ $this->configuration->parameters->server
166
+ );
167
+ }
168
+ return $this->serverMappings;
169
+ }
170
+
171
+ private function retrieveMappings(\SimpleXMLElement $section)
172
+ {
173
+ $mappings = array();
174
+ if (isset($section->mapping)) {
175
+ //load mappings
176
+ foreach($section->mapping as $rule) {
177
+ $mappings[(string)$rule->attributes()->from] =
178
+ (string)$rule->attributes()->to;
179
+ }
180
+ }
181
+ return $mappings;
182
+ }
183
+
184
+ public function getIgnoredClientParameters()
185
+ {
186
+ if ($this->ignoredClientParameters == null) {
187
+ $this->ignoredClientParameters = $this->retrieveIgnoredParameters(
188
+ $this->configuration->parameters->client
189
+ );
190
+ }
191
+ return $this->ignoredClientParameters;
192
+ }
193
+
194
+ public function getIgnoredServerParameters()
195
+ {
196
+ if ($this->ignoredServerParameters == null) {
197
+ $this->ignoredServerParameters = $this->retrieveIgnoredParameters(
198
+ $this->configuration->parameters->server
199
+ );
200
+ }
201
+ return $this->ignoredServerParameters;
202
+ }
203
+
204
+ private function retrieveIgnoredParameters(\SimpleXMLElement $section)
205
+ {
206
+ $ignoredParameters = array();
207
+ if (isset($section->ignore)) {
208
+ //load ignore rules
209
+ foreach($section->ignore as $rule) {
210
+ $ignoredParameters[(string)$rule->attributes()->name] = true;
211
+ }
212
+ }
213
+ return $ignoredParameters;
214
+ }
215
+
216
+ public function getWhitelistClientParameters()
217
+ {
218
+ if ($this->whitelistClientParameters == null) {
219
+ $this->whitelistClientParameters = $this->retrieveWhitelistParameters(
220
+ $this->configuration->parameters->client
221
+ );
222
+ }
223
+ return $this->whitelistClientParameters;
224
+ }
225
+
226
+ public function getWhitelistServerParameters()
227
+ {
228
+ if ($this->whitelistServerParameters == null) {
229
+ $this->whitelistServerParameters = $this->retrieveWhitelistParameters(
230
+ $this->configuration->parameters->server
231
+ );
232
+ if (empty($this->whitelistServerParameters)) {
233
+ $this->whitelistServerParameters = parent::getWhitelistServerParameters();
234
+ }
235
+ }
236
+ return $this->whitelistServerParameters;
237
+ }
238
+
239
+ private function retrieveWhitelistParameters(\SimpleXMLElement $section)
240
+ {
241
+ $whitelist = array();
242
+ if (isset($section->whitelist)) {
243
+ //load whitelist
244
+ foreach($section->whitelist as $rule) {
245
+ $whitelist[(string)$rule->attributes()->name] = true;
246
+ }
247
+ }
248
+ return $whitelist;
249
+ }
250
+
251
+ public function getRequiredClientParameters()
252
+ {
253
+ if ($this->requiredClientParameters == null) {
254
+ $this->requiredClientParameters = $this->retrieveRequiredParameters(
255
+ $this->configuration->parameters->client
256
+ );
257
+ }
258
+ return $this->requiredClientParameters;
259
+ }
260
+
261
+ public function getRequiredServerParameters()
262
+ {
263
+ if ($this->requiredServerParameters == null) {
264
+ $this->requiredServerParameters = $this->retrieveRequiredParameters(
265
+ $this->configuration->parameters->server
266
+ );
267
+ }
268
+ return $this->requiredServerParameters;
269
+ }
270
+
271
+ private function retrieveRequiredParameters(\SimpleXMLElement $section)
272
+ {
273
+ $requiredParameters = array();
274
+ if (isset($section->require)) {
275
+ //load require rules
276
+ foreach($section->require as $rule) {
277
+ $requiredParameters[(string)$rule->attributes()->name] =
278
+ (string)$rule->attributes()->default;
279
+ }
280
+ }
281
+ return $requiredParameters;
282
+ }
283
+
284
+ public function getDefaultConnectTimeout()
285
+ {
286
+ return (int)$this->configuration->connection->timeouts->defaultConnectTimeout;
287
+ }
288
+
289
+ public function getDefaultTimeout()
290
+ {
291
+ return (int)$this->configuration->connection->timeouts->defaultTimeout;
292
+ }
293
+
294
+ public function getSuggestConnectTimeout()
295
+ {
296
+ return (int)$this->configuration->connection->timeouts->suggestConnectTimeout;
297
+ }
298
+
299
+ public function getSuggestTimeout()
300
+ {
301
+ return (int)$this->configuration->connection->timeouts->suggestTimeout;
302
+ }
303
+
304
+ public function getTrackingConnectTimeout()
305
+ {
306
+ return (int)$this->configuration->connection->timeouts->trackingConnectTimeout;
307
+ }
308
+
309
+ public function getTrackingTimeout()
310
+ {
311
+ return (int)$this->configuration->connection->timeouts->trackingTimeout;
312
+ }
313
+
314
+ public function getImportConnectTimeout()
315
+ {
316
+ return (int)$this->configuration->connection->timeouts->importConnectTimeout;
317
+ }
318
+
319
+ public function getImportTimeout()
320
+ {
321
+ return (int)$this->configuration->connection->timeouts->importTimeout;
322
+ }
323
+
324
+ public function getPageContentEncoding()
325
+ {
326
+ if (is_null($this->pageContentEncoding))
327
+ $this->pageContentEncoding = (string)$this->configuration->encoding->pageContent;
328
+
329
+ return $this->pageContentEncoding;
330
+ }
331
+
332
+ public function getClientUrlEncoding()
333
+ {
334
+ if (is_null($this->clientUrlEncoding))
335
+ $this->clientUrlEncoding = (string)$this->configuration->encoding->clientUrl;
336
+
337
+ return $this->clientUrlEncoding;
338
+ }
339
+
340
+ public function setPageContentEncoding($encoding)
341
+ {
342
+ $this->pageContentEncoding = (string)$encoding;
343
+ }
344
+
345
+ public function setClientUrlEncoding($encoding)
346
+ {
347
+ $this->clientUrlEncoding = (string)$encoding;
348
+ }
349
+ }
lib/FACTFinder/Curl.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
- /**
3
- * Implements the cURL interface by simply delegating calls to the built-in cURL functions..
4
- * See http://www.php.net/manual/en/book.curl.php
5
- **/
6
- class FACTFinder_Curl
7
- implements FACTFinder_CurlInterface
8
- {
9
-
10
- public function curl_close($ch)
11
- {
12
- curl_close($ch);
13
- }
14
-
15
- public function curl_copy_handle($ch)
16
- {
17
- return curl_copy_handle($ch);
18
- }
19
-
20
- public function curl_errno($ch)
21
- {
22
- return curl_errno($ch);
23
- }
24
-
25
- public function curl_error($ch)
26
- {
27
- return curl_error($ch);
28
- }
29
-
30
- public function curl_exec($ch)
31
- {
32
- return curl_exec($ch);
33
- }
34
-
35
- public function curl_getinfo($ch, $opt = 0)
36
- {
37
- return curl_getinfo($ch, $opt);
38
- }
39
-
40
- public function curl_init($url = null)
41
- {
42
- return curl_init($url);
43
- }
44
-
45
- public function curl_multi_add_handle($mh, $ch)
46
- {
47
- return curl_multi_add_handle($mh, $ch);
48
- }
49
-
50
- public function curl_multi_close($mh)
51
- {
52
- curl_multi_close($mh);
53
- }
54
-
55
- public function curl_multi_exec($mh, &$still_running)
56
- {
57
- return curl_multi_exec($mh, $still_running);
58
- }
59
-
60
- public function curl_multi_getcontent($ch)
61
- {
62
- return curl_multi_getcontent($ch);
63
- }
64
-
65
- public function curl_multi_info_read($mh, &$msgs_in_queue = null)
66
- {
67
- return curl_multi_info_read($mh, $msgs_in_queue);
68
- }
69
-
70
- public function curl_multi_init()
71
- {
72
- return curl_multi_init();
73
- }
74
-
75
- public function curl_multi_remove_handle($mh, $ch)
76
- {
77
- return curl_multi_remove_handle($mh, $ch);
78
- }
79
-
80
- public function curl_multi_select($mh, $timeout = 1.0)
81
- {
82
- return curl_multi_select($mh, $timeout);
83
- }
84
-
85
- public function curl_setopt_array($ch, $options)
86
- {
87
- return curl_setopt_array($ch, $options);
88
- }
89
-
90
- public function curl_setopt($ch, $option, $value)
91
- {
92
- return curl_setopt($ch, $option, $value);
93
- }
94
-
95
- public function curl_version($age = CURLVERSION_NOW)
96
- {
97
- return curl_version($age);
98
- }
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/CurlHandle.php DELETED
@@ -1,8 +0,0 @@
1
- <?php
2
- /**
3
- * Struct-like class that represents all data associated with one curl handle
4
- **/
5
- class FACTFinder_CurlHandle
6
- {
7
- public $options;
8
- }
 
 
 
 
 
 
 
 
lib/FACTFinder/CurlInterface.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * Interface for PHP cURL functions.
4
- **/
5
- interface FACTFinder_CurlInterface
6
- {
7
- public function curl_close($ch);
8
- public function curl_copy_handle($ch);
9
- public function curl_errno($ch);
10
- public function curl_error($ch);
11
- public function curl_exec($ch);
12
- public function curl_getinfo($ch, $opt = 0);
13
- public function curl_init($url = null);
14
- public function curl_multi_add_handle($mh, $ch);
15
- public function curl_multi_close($mh);
16
- public function curl_multi_exec($mh, &$still_running);
17
- public function curl_multi_getcontent($ch);
18
- public function curl_multi_info_read($mh, &$msgs_in_queue = null);
19
- public function curl_multi_init();
20
- public function curl_multi_remove_handle($mh, $ch);
21
- public function curl_multi_select($mh, $timeout = 1.0);
22
- public function curl_setopt_array($ch, $options);
23
- public function curl_setopt($ch, $option, $value);
24
- public function curl_version($age = CURLVERSION_NOW);
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/FACTFinder/CurlStub.php DELETED
@@ -1,379 +0,0 @@
1
- <?php
2
- /**
3
- * Stubs the cURL interface without issuing any PHP requests.
4
- **/
5
-
6
- class FACTFinder_CurlStub
7
- implements FACTFinder_CurlInterface
8
- {
9
- private $_lastHandle = -1;
10
-
11
- private $_mapOptionCounts = array();
12
- private $_mapOptions = array();
13
- private $_mapResponses = array();
14
- private $_mapErrorCodes = array();
15
- private $_mapInfo = array();
16
-
17
- /**
18
- * @var array of FACTFinder_CurlHandle
19
- */
20
- private $_handles = array();
21
-
22
- public function curl_close($ch)
23
- {
24
- unset($this->_handles[$ch]);
25
- }
26
-
27
- public function curl_copy_handle($ch)
28
- {
29
- $newCh = ++$this->_lastHandle;
30
-
31
- $handle = clone $this->_handles[$ch];
32
-
33
- $this->_handles[$newCh] = $handle;
34
-
35
- return $newCh;
36
- }
37
-
38
- public function curl_errno($ch)
39
- {
40
- if(!isset($this->_handles[$ch]))
41
- return 0;
42
-
43
- return $this->_getErrorCode($this->_handles[$ch]);
44
- }
45
-
46
- public function curl_error($ch)
47
- {
48
- $errno = $this->curl_errno($ch);
49
- return FACTFinder_CurlStub::$errorLookup[$errno];
50
- }
51
-
52
- public function curl_exec($ch)
53
- {
54
- if(!isset($this->_handles[$ch]))
55
- return false;
56
-
57
- /**
58
- * @var $handle FACTFinder_CurlHandle
59
- */
60
- $handle = $this->_handles[$ch];
61
-
62
- $response = $this->_getResponse($handle);
63
-
64
- if($response === null)
65
- return false;
66
-
67
- if($handle->options[CURLOPT_RETURNTRANSFER])
68
- return $response;
69
-
70
- echo $response;
71
- return true;
72
- }
73
-
74
- public function curl_getinfo($ch, $opt = 0)
75
- {
76
- // TODO: Include logic to build CURLINFO_EFFECTIVE_URL?
77
- if(!isset($this->_handles[$ch]))
78
- trigger_error(__FUNCTION__.'(): '.$ch.' is not a valid cURL handle resource', E_USER_WARNING);
79
-
80
- if($opt == 0)
81
- return $this->_getInfoArray($this->_handles[$ch]);
82
-
83
- return $this->_getInfo($this->_handles[$ch], $opt);
84
- }
85
-
86
- public function curl_init($url = null)
87
- {
88
- $ch = ++$this->_lastHandle;
89
-
90
- $handle = FF::getInstance('curlHandle');
91
-
92
- $handle->options = array(
93
- CURLOPT_RETURNTRANSFER => false
94
- );
95
-
96
- $this->_handles[$ch] = $handle;
97
-
98
- if($url !== null)
99
- $this->curl_setopt($ch, CURLOPT_URL, $url);
100
-
101
- return $ch;
102
- }
103
-
104
- public function curl_multi_add_handle($mh, $ch)
105
- {
106
- throw new Exception("Not yet implemented.");
107
- }
108
-
109
- public function curl_multi_close($mh)
110
- {
111
- throw new Exception("Not yet implemented.");
112
- }
113
-
114
- public function curl_multi_exec($mh, &$still_running)
115
- {
116
- throw new Exception("Not yet implemented.");
117
- }
118
-
119
- public function curl_multi_getcontent($ch)
120
- {
121
- throw new Exception("Not yet implemented.");
122
- }
123
-
124
- public function curl_multi_info_read($mh, &$msgs_in_queue = null)
125
- {
126
- throw new Exception("Not yet implemented.");
127
- }
128
-
129
- public function curl_multi_init()
130
- {
131
- throw new Exception("Not yet implemented.");
132
- }
133
-
134
- public function curl_multi_remove_handle($mh, $ch)
135
- {
136
- throw new Exception("Not yet implemented.");
137
- }
138
-
139
- public function curl_multi_select($mh, $timeout = 1.0)
140
- {
141
- throw new Exception("Not yet implemented.");
142
- }
143
-
144
- public function curl_setopt_array($ch, $options)
145
- {
146
- foreach($options as $option => $value)
147
- {
148
- if(!$this->curl_setopt($ch, $option, $value))
149
- return false;
150
- }
151
- return true;
152
- }
153
-
154
- public function curl_setopt($ch, $option, $value)
155
- {
156
- if(!isset($this->_handles[$ch]))
157
- return false;
158
-
159
- $this->_handles[$ch]->options[$option] = $value;
160
-
161
- return true;
162
- }
163
-
164
- public function curl_version($age = CURLVERSION_NOW)
165
- {
166
- return curl_version($age);
167
- }
168
-
169
- public function setResponse($expectedResponse, $requiredOptions = array())
170
- {
171
- $hash = $this->_getHashAndSetOptionMaps($requiredOptions);
172
- $this->_mapResponses[$hash] = $expectedResponse;
173
- }
174
-
175
- public function setErrorCode($expectedErrorCode, $requiredOptions = array())
176
- {
177
- $hash = $this->_getHashAndSetOptionMaps($requiredOptions);
178
- $this->_mapErrorCodes[$hash] = $expectedErrorCode;
179
- }
180
-
181
- public function setInfo($expectedInfo, $requiredOptions = array())
182
- {
183
- $hash = $this->_getHashAndSetOptionMaps($requiredOptions);
184
- $this->_mapInfo[$hash] = $expectedInfo;
185
- }
186
-
187
- private function _getHashAndSetOptionMaps($requiredOptions)
188
- {
189
- $hash = md5(http_build_query($requiredOptions));
190
-
191
- $this->_mapOptionCounts[$hash] = count($requiredOptions);
192
- arsort($this->_mapOptionCounts);
193
- $this->_mapOptions[$hash] = $requiredOptions;
194
- return $hash;
195
- }
196
-
197
- private function _getResponse($handle)
198
- {
199
- $response = false;
200
-
201
- $key = $this->_determineKey($handle);
202
-
203
- if($key !== null && isset($this->_mapResponses[$key]))
204
- $response = $this->_mapResponses[$key];
205
-
206
- return $response;
207
- }
208
-
209
- private function _getErrorCode($handle)
210
- {
211
- $errorCode = 0;
212
-
213
- $key = $this->_determineKey($handle);
214
-
215
- if($key !== null && isset($this->_mapErrorCodes[$key]))
216
- $errorCode = $this->_mapErrorCodes[$key];
217
-
218
- return $errorCode;
219
- }
220
-
221
- private function _getInfo($handle, $opt)
222
- {
223
- $info = '';
224
-
225
- $key = $this->_determineKey($handle);
226
-
227
- if($key !== null && isset($this->_mapInfo[$key][$opt]))
228
- $info = $this->_mapInfo[$key][$opt];
229
-
230
- return $info;
231
- }
232
-
233
- private function _getInfoArray($handle)
234
- {
235
- $infoArray = array();
236
-
237
- foreach(self::$infoLookup as $strKey)
238
- {
239
- $infoArray[$strKey] = '';
240
- }
241
-
242
- $handleKey = $this->_determineKey($handle);
243
-
244
- if($handleKey !== null && isset($this->_mapInfo[$handleKey]))
245
- {
246
- foreach($this->_mapInfo[$handleKey] as $intKey => $value)
247
- {
248
- $strKey = self::$infoLookup[$intKey];
249
- $infoArray[$strKey] = $value;
250
- }
251
- }
252
-
253
- return $infoArray;
254
- }
255
-
256
- private function _determineKey($handle)
257
- {
258
- // TODO: Treat URL separately, so that order of parameters does not matter
259
- $returnValue = null;
260
- $options = $handle->options;
261
- foreach($this->_mapOptionCounts as $hash => $optionCount)
262
- {
263
- foreach($this->_mapOptions[$hash] as $option => $value)
264
- {
265
- if(!isset($options[$option]) || $options[$option] != $value)
266
- continue 2;
267
- }
268
-
269
- $returnValue = $hash;
270
-
271
- break;
272
- }
273
- return $returnValue;
274
- }
275
-
276
- private static $errorLookup = array(
277
- 0 => 'CURLE_OK',
278
- 1 => 'CURLE_UNSUPPORTED_PROTOCOL',
279
- 2 => 'CURLE_FAILED_INIT',
280
- 3 => 'CURLE_URL_MALFORMAT',
281
- 4 => 'CURLE_URL_MALFORMAT_USER',
282
- 5 => 'CURLE_COULDNT_RESOLVE_PROXY',
283
- 6 => 'CURLE_COULDNT_RESOLVE_HOST',
284
- 7 => 'CURLE_COULDNT_CONNECT',
285
- 8 => 'CURLE_FTP_WEIRD_SERVER_REPLY',
286
- 9 => 'CURLE_REMOTE_ACCESS_DENIED',
287
- 11 => 'CURLE_FTP_WEIRD_PASS_REPLY',
288
- 13 => 'CURLE_FTP_WEIRD_PASV_REPLY',
289
- 14 => 'CURLE_FTP_WEIRD_227_FORMAT',
290
- 15 => 'CURLE_FTP_CANT_GET_HOST',
291
- 17 => 'CURLE_FTP_COULDNT_SET_TYPE',
292
- 18 => 'CURLE_PARTIAL_FILE',
293
- 19 => 'CURLE_FTP_COULDNT_RETR_FILE',
294
- 21 => 'CURLE_QUOTE_ERROR',
295
- 22 => 'CURLE_HTTP_RETURNED_ERROR',
296
- 23 => 'CURLE_WRITE_ERROR',
297
- 25 => 'CURLE_UPLOAD_FAILED',
298
- 26 => 'CURLE_READ_ERROR',
299
- 27 => 'CURLE_OUT_OF_MEMORY',
300
- 28 => 'CURLE_OPERATION_TIMEOUTED', // in the original cURL lib this is called 'CURLE_OPERATION_TIMEOUTED' instead
301
- 30 => 'CURLE_FTP_PORT_FAILED',
302
- 31 => 'CURLE_FTP_COULDNT_USE_REST',
303
- 33 => 'CURLE_RANGE_ERROR',
304
- 34 => 'CURLE_HTTP_POST_ERROR',
305
- 35 => 'CURLE_SSL_CONNECT_ERROR',
306
- 36 => 'CURLE_BAD_DOWNLOAD_RESUME',
307
- 37 => 'CURLE_FILE_COULDNT_READ_FILE',
308
- 38 => 'CURLE_LDAP_CANNOT_BIND',
309
- 39 => 'CURLE_LDAP_SEARCH_FAILED',
310
- 41 => 'CURLE_FUNCTION_NOT_FOUND',
311
- 42 => 'CURLE_ABORTED_BY_CALLBACK',
312
- 43 => 'CURLE_BAD_FUNCTION_ARGUMENT',
313
- 45 => 'CURLE_INTERFACE_FAILED',
314
- 47 => 'CURLE_TOO_MANY_REDIRECTS',
315
- 48 => 'CURLE_UNKNOWN_TELNET_OPTION',
316
- 49 => 'CURLE_TELNET_OPTION_SYNTAX',
317
- 51 => 'CURLE_PEER_FAILED_VERIFICATION',
318
- 52 => 'CURLE_GOT_NOTHING',
319
- 53 => 'CURLE_SSL_ENGINE_NOTFOUND',
320
- 54 => 'CURLE_SSL_ENGINE_SETFAILED',
321
- 55 => 'CURLE_SEND_ERROR',
322
- 56 => 'CURLE_RECV_ERROR',
323
- 58 => 'CURLE_SSL_CERTPROBLEM',
324
- 59 => 'CURLE_SSL_CIPHER',
325
- 60 => 'CURLE_SSL_CACERT',
326
- 61 => 'CURLE_BAD_CONTENT_ENCODING',
327
- 62 => 'CURLE_LDAP_INVALID_URL',
328
- 63 => 'CURLE_FILESIZE_EXCEEDED',
329
- 64 => 'CURLE_USE_SSL_FAILED',
330
- 65 => 'CURLE_SEND_FAIL_REWIND',
331
- 66 => 'CURLE_SSL_ENGINE_INITFAILED',
332
- 67 => 'CURLE_LOGIN_DENIED',
333
- 68 => 'CURLE_TFTP_NOTFOUND',
334
- 69 => 'CURLE_TFTP_PERM',
335
- 70 => 'CURLE_REMOTE_DISK_FULL',
336
- 71 => 'CURLE_TFTP_ILLEGAL',
337
- 72 => 'CURLE_TFTP_UNKNOWNID',
338
- 73 => 'CURLE_REMOTE_FILE_EXISTS',
339
- 74 => 'CURLE_TFTP_NOSUCHUSER',
340
- 75 => 'CURLE_CONV_FAILED',
341
- 76 => 'CURLE_CONV_REQD',
342
- 77 => 'CURLE_SSL_CACERT_BADFILE',
343
- 78 => 'CURLE_REMOTE_FILE_NOT_FOUND',
344
- 79 => 'CURLE_SSH',
345
- 80 => 'CURLE_SSL_SHUTDOWN_FAILED',
346
- 81 => 'CURLE_AGAIN',
347
- 82 => 'CURLE_SSL_CRL_BADFILE',
348
- 83 => 'CURLE_SSL_ISSUER_ERROR',
349
- 84 => 'CURL E_FTP_PRET_FAILED',
350
- 85 => 'CURLE_RTSP_CSEQ_ERROR',
351
- 86 => 'CURLE_RTSP_SESSION_ERROR',
352
- 87 => 'CURLE_FTP_BAD_FILE_LIST',
353
- 88 => 'CURLE_CHUNK_FAILED'
354
- );
355
-
356
- public static $infoLookup = array(
357
- CURLINFO_EFFECTIVE_URL => 'url',
358
- CURLINFO_HTTP_CODE => 'http_code',
359
- CURLINFO_FILETIME => 'filetime',
360
- CURLINFO_TOTAL_TIME => 'total_time',
361
- CURLINFO_NAMELOOKUP_TIME => 'namelookup_time',
362
- CURLINFO_CONNECT_TIME => 'connect_time',
363
- CURLINFO_PRETRANSFER_TIME => 'pretransfer_time',
364
- CURLINFO_STARTTRANSFER_TIME => 'starttransfer_time',
365
- CURLINFO_REDIRECT_COUNT => 'redirect_count',
366
- CURLINFO_REDIRECT_TIME => 'redirect_time',
367
- CURLINFO_SIZE_UPLOAD => 'size_upload',
368
- CURLINFO_SIZE_DOWNLOAD => 'size_download',
369
- CURLINFO_SPEED_DOWNLOAD => 'speed_download',
370
- CURLINFO_SPEED_UPLOAD => 'speed_upload',
371
- CURLINFO_HEADER_SIZE => 'header_size',
372
- CURLINFO_HEADER_OUT => 'request_header',
373
- CURLINFO_REQUEST_SIZE => 'request_size',
374
- CURLINFO_SSL_VERIFYRESULT => 'ssl_verify_result',
375
- CURLINFO_CONTENT_LENGTH_DOWNLOAD =>