PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/community/Fishpig/Wordpress/Helper/Associations.php

https://gitlab.com/hennesfinest/wordpress-integration
PHP | 472 lines | 276 code | 73 blank | 123 comment | 35 complexity | 86d1ef4b0c54a313e1366be26b8b7165 MD5 | raw file
  1. <?php
  2. /**
  3. * @category Fishpig
  4. * @package Fishpig_Wordpress
  5. * @license http://fishpig.co.uk/license.txt
  6. * @author Ben Tideswell <help@fishpig.co.uk>
  7. */
  8. class Fishpig_Wordpress_Helper_Associations extends Fishpig_Wordpress_Helper_Abstract
  9. {
  10. /**
  11. * Retrieve a collection of post's associated with the given product
  12. *
  13. * @param Mage_Catalog_Model_Product $product
  14. * @return false|Fishpig_Wordpress_Model_Resource_Post_Collection_Abstract
  15. */
  16. public function getAssociatedPostsByProduct(Mage_Catalog_Model_Product $product)
  17. {
  18. if (!($product instanceof Mage_Catalog_Model_Product)) {
  19. return false;
  20. }
  21. $associations = array_keys($this->getAssociations('product/post', $product->getId()));
  22. $categoryAssociations = array_keys($this->getAssociations('product/category', $product->getId()));
  23. $associations = array_merge($associations, $this->_convertWpCategoryIds($categoryAssociations));
  24. foreach($product->getCategoryIds() as $categoryId) {
  25. $associations = array_merge($associations, array_keys($this->getAssociations('category/post', $categoryId)));
  26. $categoryAssociations = array_keys($this->getAssociations('category/category', $categoryId));
  27. $associations = array_merge($associations, $this->_convertWpCategoryIds($categoryAssociations));
  28. }
  29. if (count($associations) > 0) {
  30. return Mage::getResourceModel('wordpress/post_collection')
  31. ->addFieldToFilter('ID', array('IN' => $associations))
  32. ->addIsPublishedFilter();
  33. }
  34. return false;
  35. }
  36. /**
  37. * Retrieve a collection of post's associated with the given product
  38. *
  39. * @param Mage_Cms_Model_Page $page
  40. * @return false|Fishpig_Wordpress_Model_Resource_Post_Collection_Abstract
  41. */
  42. public function getAssociatedPostsByCmsPage(Mage_Cms_Model_Page $page)
  43. {
  44. if (!($page instanceof Mage_Cms_Model_Page)) {
  45. return false;
  46. }
  47. $associations = array_keys($this->getAssociations('cms_page/post', $page->getId(), 0));
  48. $categoryAssociations = array_keys($this->getAssociations('cms_page/category', $page->getId(), 0));
  49. $associations = array_merge($associations, $this->_convertWpCategoryIds($categoryAssociations));
  50. if (count($associations) > 0) {
  51. return Mage::getResourceModel('wordpress/post_collection')
  52. ->addFieldToFilter('ID', array('IN' => $associations))
  53. ->addIsPublishedFilter();
  54. }
  55. return false;
  56. }
  57. /**
  58. * Retrieve a collection of products assocaited with the post
  59. *
  60. * @param Fishpig_Wordpress_Model_Post $post
  61. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
  62. */
  63. public function getAssociatedProductsByPost(Fishpig_Wordpress_Model_Post_Abstract $post)
  64. {
  65. if (!($post instanceof Fishpig_Wordpress_Model_Post)) {
  66. return false;
  67. }
  68. $associations = array_keys($this->getReverseAssociations('product/post', $post->getId()));
  69. foreach($post->getParentCategories() as $category) {
  70. $associations = array_merge($associations, array_keys($this->getReverseAssociations('product/category', $category->getId())));
  71. }
  72. $associations = array_unique($associations);
  73. if (count($associations) > 0) {
  74. $collection = Mage::getResourceModel('catalog/product_collection');
  75. Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
  76. if (!Mage::getStoreConfigFlag('cataloginventory/options/show_out_of_stock')) {
  77. Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
  78. }
  79. $collection->addAttributeToFilter('status', 1);
  80. $collection->addAttributeToFilter('entity_id', array('in' => $associations));
  81. return $collection;
  82. }
  83. return false;
  84. }
  85. /**
  86. * Retrieve an array of associated ID's and their position value
  87. *
  88. * @param string $type
  89. * @param int $objectId
  90. * @param int|null $storeId = null
  91. * @return array|false
  92. */
  93. public function getAssociations($type, $objectId, $storeId = null)
  94. {
  95. return $this->_getAssociations($type, $objectId, $storeId, 'object_id', 'wordpress_object_id');
  96. }
  97. /**
  98. * Retrieve an array of associated ID's and their position value
  99. * This receives a post ID and returns the associated Magento product ID's
  100. *
  101. * @param string $type
  102. * @param int $objectId
  103. * @param int|null $storeId = null
  104. * @return array
  105. */
  106. public function getReverseAssociations($type, $objectId, $storeId = null)
  107. {
  108. return $this->_getAssociations($type, $objectId, $storeId, 'wordpress_object_id', 'object_id');
  109. }
  110. /**
  111. * Retrieve an array of associated ID's and their position value
  112. *
  113. * @param string $type
  114. * @param int $objectId
  115. * @param int|null $storeId = null
  116. * @return array
  117. */
  118. protected function _getAssociations($type, $objectId, $storeId = null, $filter, $return)
  119. {
  120. if (($typeId = $this->getTypeId($type)) !== false) {
  121. if (is_null($storeId)) {
  122. $storeId = Mage::app()->getStore()->getId();
  123. }
  124. $select = $this->_getReadAdapter()
  125. ->select()
  126. ->from($this->_getTable('wordpress/association'), array($return, 'position'))
  127. ->where('type_id=?', $typeId)
  128. ->where($filter . '=?', $objectId)
  129. ->where('store_id=?', $storeId)
  130. ->order('position ASC');
  131. try {
  132. if (($results = $this->_getReadAdapter()->fetchAll($select)) !== false) {
  133. $associations = array();
  134. foreach($results as $result) {
  135. $associations[$result[$return]] = $result['position'];
  136. }
  137. return $associations;
  138. }
  139. }
  140. catch (Exception $e) {
  141. $this->log($e);
  142. }
  143. }
  144. return array();
  145. }
  146. /**
  147. * Delete all associations for a type/object_id/store combination
  148. *
  149. * @param string $type
  150. * @param int $objectId
  151. * @param int|null $storeId = null
  152. * @return $this
  153. */
  154. public function deleteAssociations($type, $objectId, $storeId = null)
  155. {
  156. if (($typeId = $this->getTypeId($type)) !== false) {
  157. if (is_null($storeId)) {
  158. $storeId = Mage::app()->getStore()->getId();
  159. }
  160. $write = $this->_getWriteAdapter();
  161. $table = $this->_getTable('wordpress/association');
  162. $cond = implode(' AND ', array(
  163. $write->quoteInto('object_id=?', $objectId),
  164. $write->quoteInto('type_id=?', $typeId),
  165. $write->quoteInto('store_id=?', $storeId),
  166. ));
  167. $write->delete($table, $cond, $storeId);
  168. $write->commit();
  169. }
  170. return $this;
  171. }
  172. /**
  173. * Create associations
  174. *
  175. * @param string $type
  176. * @param int $objectId
  177. * @param array $associations
  178. * @param int|null $storeId = null
  179. * @return $this
  180. */
  181. public function createAssociations($type, $objectId, array $associations, $storeId = null)
  182. {
  183. if (count($associations) === 0) {
  184. return $this;
  185. }
  186. if (($typeId = $this->getTypeId($type)) !== false) {
  187. if (is_null($storeId)) {
  188. $storeId = Mage::app()->getStore()->getId();
  189. }
  190. $write = $this->_getWriteAdapter();
  191. $table = $this->_getTable('wordpress/association');
  192. foreach($associations as $wpObjectId => $data) {
  193. if (is_array($data)) {
  194. $position = array_shift($data);
  195. }
  196. else {
  197. $position = 0;
  198. $wpObjectId = $data;
  199. }
  200. $write->insert($table, array(
  201. 'type_id' => $typeId,
  202. 'object_id' => $objectId,
  203. 'wordpress_object_id' => $wpObjectId,
  204. 'position' => $position,
  205. 'store_id' => $storeId,
  206. ));
  207. $write->commit();
  208. }
  209. }
  210. return $this;
  211. }
  212. /**
  213. * Process an observer triggered to save associations
  214. * This only works for certain models
  215. *
  216. * @param Varien_Event_Observer $observer
  217. * @return bool
  218. */
  219. public function processObserver(Varien_Event_Observer $observer)
  220. {
  221. $storeIds = $this->getAssociationStoreIds();
  222. if (($product = $observer->getEvent()->getProduct()) !== null) {
  223. $objectId = $product->getId();
  224. }
  225. else if (($category = $observer->getEvent()->getCategory()) !== null) {
  226. $objectId = $category->getId();
  227. }
  228. else if ($observer->getEvent()->getObject() instanceof Mage_Cms_Model_Page) {
  229. $objectId = $observer->getEvent()->getObject()->getId();
  230. $storeIds = array(0);
  231. }
  232. else {
  233. return false;
  234. }
  235. $post = Mage::app()->getRequest()->getPost('wp');
  236. if (!isset($post['assoc'])) {
  237. return false;
  238. }
  239. $assocData = $post['assoc'];
  240. foreach($assocData as $object => $data) {
  241. foreach($data as $wpObject => $associations) {
  242. $associations = Mage::helper('adminhtml/js')->decodeGridSerializedInput($associations);
  243. $type = $object . '/' . $wpObject;
  244. foreach($storeIds as $storeId) {
  245. $this->deleteAssociations($type, $objectId, $storeId)
  246. ->createAssociations($type, $objectId, $associations, $storeId);
  247. }
  248. }
  249. }
  250. }
  251. /**
  252. * Retrieve a type_id associated with the given type
  253. *
  254. * @param string $type
  255. * @return int|false
  256. */
  257. public function getTypeId($type)
  258. {
  259. if (strpos($type, '/') !== false) {
  260. $types = explode('/', $type);
  261. $select = $this->_getReadAdapter()
  262. ->select()
  263. ->from($this->_getTable('wordpress/association_type'), 'type_id')
  264. ->where('object=?', $types[0])
  265. ->where('wordpress_object=?', $types[1])
  266. ->limit(1);
  267. return $this->_getReadAdapter()->fetchOne($select);
  268. }
  269. return false;
  270. }
  271. /**
  272. * Add the position value for the association between each item and the $type and $objectId
  273. * combination
  274. *
  275. * @param $collection
  276. * @param string $type
  277. * @param int $objectId
  278. * @return $this
  279. */
  280. public function addRelatedPositionToSelect($collection, $type, $objectId, $storeId = null)
  281. {
  282. if (($typeId = Mage::helper('wordpress/associations')->getTypeId($type)) !== false) {
  283. if (is_null($storeId)) {
  284. $storeId = array((int)Mage::app()->getStore()->getId(), 0);
  285. }
  286. else if (!is_array($storeId)) {
  287. $storeId = array($storeId, 0);
  288. }
  289. $field = strpos($type, '/category') !== false ? 'term_id' : 'ID';
  290. $cond = implode(' AND ', array(
  291. '`assoc`.`wordpress_object_id` = `main_table`.`' . $field . '`',
  292. '`assoc`.`object_id` = ' . (int)$objectId,
  293. '`assoc`.`type_id` = ' . (int)$typeId,
  294. $collection->getConnection()->quoteInto('`assoc`.`store_id` IN (?)', $storeId),
  295. ));
  296. $dbname = $collection->getTable('wordpress/association');
  297. if (!Mage::helper('wordpress/database')->isSameDatabase()) {
  298. $dbname = (string)Mage::getConfig()->getNode('global/resources/default_setup/connection/dbname') . '.' . $dbname;
  299. }
  300. $collection->getSelect()
  301. ->distinct()
  302. ->joinLeft(
  303. array('assoc' => $dbname),
  304. $cond,
  305. array('associated_position' => 'IF(ISNULL(position), 4444, position)', 'is_associated' => 'IF(ISNULL(assoc.position), 0, 1)')
  306. );
  307. $collection->getSelect()->order('assoc.store_id DESC');
  308. // ->order('assoc.position ASC');
  309. }
  310. return $this;
  311. }
  312. /**
  313. * Retrieve the current store ID
  314. * If no store ID is set or site is multistore, return default store ID
  315. *
  316. * @return int
  317. */
  318. public function getAssociationStoreIds()
  319. {
  320. $singleStore = Mage::app()->isSingleStoreMode() && Mage::helper('wordpress')->forceSingleStore();
  321. if (!$singleStore && ($storeId = (int)Mage::app()->getRequest()->getParam('store'))) {
  322. return array($storeId);
  323. }
  324. $select = $this->_getReadAdapter()
  325. ->select()
  326. ->from($this->_getTable('core/store'), 'store_id')
  327. ->where('store_id>?', 0);
  328. return $this->_getReadAdapter()->fetchCol($select);
  329. }
  330. /**
  331. * Retrieve a single store ID
  332. *
  333. * @return int
  334. */
  335. public function getSingleStoreId()
  336. {
  337. $storeIds = $this->getAssociationStoreIds();
  338. if (is_array($storeIds)) {
  339. return (int)array_shift($storeIds);
  340. }
  341. return (int)$storeIds;
  342. }
  343. /**
  344. * Convert an array of WordPress category ID's to
  345. * an array of post ID's
  346. *
  347. * @param array $categoryIds
  348. * @return array
  349. */
  350. protected function _convertWpCategoryIds(array $categoryIds)
  351. {
  352. if (count($categoryIds) === 0) {
  353. return array();
  354. }
  355. $select = $this->_getReadAdapter()
  356. ->select()
  357. ->from(array('term' => $this->_getTable('wordpress/term')), '')
  358. ->where('term.term_id IN (?)', $categoryIds);
  359. $select->join(
  360. array('tax' => $this->_getTable('wordpress/term_taxonomy')),
  361. "`tax`.`term_id` = `term`.`term_id` AND `tax`.`taxonomy`= 'category'",
  362. ''
  363. );
  364. $select->join(
  365. array('rel' => $this->_getTable('wordpress/term_relationship')),
  366. "`rel`.`term_taxonomy_id` = `tax`.`term_taxonomy_id`",
  367. 'object_id'
  368. );
  369. return Mage::helper('wordpress/database')->getReadAdapter()->fetchCol($select);
  370. }
  371. /**
  372. * Retrieve the read DB adapter
  373. *
  374. * @return
  375. */
  376. protected function _getReadAdapter()
  377. {
  378. return Mage::getSingleton('core/resource')->getConnection('core_read');
  379. }
  380. /**
  381. * Retrieve the write DB adapter
  382. *
  383. * @return
  384. */
  385. protected function _getWriteAdapter()
  386. {
  387. return Mage::getSingleton('core/resource')->getConnection('core_write');
  388. }
  389. /**
  390. * Retrieve a table name by entity
  391. *
  392. * @param string $entity
  393. * @return string
  394. */
  395. protected function _getTable($entity)
  396. {
  397. return Mage::getSingleton('core/resource')->getTableName($entity);
  398. }
  399. }