├── .gitignore ├── .php_cs ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── modman └── src └── app ├── code └── community │ └── Hackathon │ └── ChatConnector │ ├── Helper │ └── Data.php │ ├── Model │ ├── Connectors │ │ ├── Abstract.php │ │ ├── HipChat.php │ │ ├── Interface.php │ │ └── Slack.php │ ├── Cron │ │ ├── Abstract.php │ │ ├── Cleanup.php │ │ └── Process.php │ ├── Events │ │ ├── Abstract.php │ │ ├── Customer │ │ │ └── Register.php │ │ ├── Interface.php │ │ ├── Newsletter │ │ │ └── Subscriber.php │ │ └── Sales │ │ │ ├── Invoice.php │ │ │ └── Order.php │ ├── Queue.php │ ├── Resource │ │ ├── Queue.php │ │ ├── Queue │ │ │ └── Collection.php │ │ └── Setup.php │ └── System │ │ └── Config │ │ └── Source │ │ └── Dropdown │ │ └── Connectors.php │ ├── Test │ ├── Config │ │ ├── Config.php │ │ └── Config │ │ │ └── expectations │ │ │ └── globalConfig.yaml │ ├── Helper │ │ ├── Data.php │ │ └── Data │ │ │ └── _data │ │ │ ├── ex-getActiveConnectors.yaml │ │ │ ├── fx-getActiveConnectors.yaml │ │ │ ├── fx-getRetryFrequency.yaml │ │ │ ├── fx-testIsActive.yaml │ │ │ └── fx-testIsNotActive.yaml │ └── Model │ │ └── Resource │ │ ├── Queue.php │ │ └── Queue │ │ └── _data │ │ ├── dp-testUpdateStatus.yaml │ │ ├── fx-testCleanupProcessedEntries.yaml │ │ └── fx-testUpdateStatus.yaml │ ├── etc │ ├── adminhtml.xml │ ├── config.xml │ └── system.xml │ └── sql │ └── hackathon_chatconnector_setup │ └── install-1.0.0.php └── etc └── modules └── Hackathon_ChatConnector.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | files() 5 | ->name('*.php') 6 | ->in(__DIR__.'/src') 7 | ; 8 | 9 | return Symfony\CS\Config\Config::create() 10 | ->fixers(array( 11 | 'psr0', 'encoding', 'short_tag', 'braces', 'elseif', 'eof_ending', 'function_declaration', 'indentation', 'line_after_namespace', 'linefeed', 'lowercase_constants', 'lowercase_keywords', 'multiple_use', 'php_closing_tag', 'trailing_spaces', 'visibility', 'duplicate_semicolon', 'extra_empty_lines', 'include', 'namespace_no_leading_whitespace', 'object_operator', 'operators_spaces', 'phpdoc_params', 'return', 'single_array_no_trailing_comma', 'spaces_cast', 'standardize_not_equal', 'ternary_spaces', 'unused_use', 'whitespacy_lines', 12 | )) 13 | ->finder($finder) 14 | ; 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.4 4 | - 5.5 5 | - 5.6 6 | matrix: 7 | allow_failures: 8 | - php: 5.6 9 | env: 10 | - MAGENTO_VERSION=magento-ce-1.7.0.2 11 | - MAGENTO_VERSION=magento-ce-1.8.1.0 12 | - MAGENTO_VERSION=magento-ce-1.9.0.1 13 | #- MAGENTO_VERSION=magento-ce-1.9.1.1 14 | script: 15 | - curl -sSL https://raw.githubusercontent.com/AOEpeople/MageTestStand/master/setup.sh | bash 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 magento-hackathon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hackathon_ChatConnector 2 | 3 | This extensions provides an integration for some popular chat and collaboration tools so that you will get notified 4 | if some events happen in your Magento store, e.g. a new order is created, a new customer signs up, etc. 5 | 6 | ## Build Status 7 | 8 | * master: [![Build Status](https://travis-ci.org/magento-hackathon/Hackathon_ChatConnector.svg?branch=master)](https://travis-ci.org/magento-hackathon/Hackathon_ChatConnector) 9 | * develop: [![Build Status](https://travis-ci.org/magento-hackathon/Hackathon_ChatConnector.svg?branch=develop)](https://travis-ci.org/magento-hackathon/Hackathon_ChatConnector) 10 | 11 | ## Current Integrations 12 | 13 | * Slack 14 | * HipChat 15 | 16 | ## Supported Events 17 | 18 | This is a list of all events in Magento that will trigger a notification for the configured chats: 19 | - customer_register_success 20 | - sales_order_payment_cancel 21 | 22 | ## Contributors 23 | 24 | * mhauri 25 | * sandermangel 26 | * woutercleymans 27 | * avoelkl 28 | * therouv 29 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magento-hackathon/hackathon_chatconnector", 3 | "license": "MIT", 4 | "type": "magento-module", 5 | "description": "", 6 | "suggest": { 7 | "magento-hackathon/magento-composer-installer": "*" 8 | }, 9 | "authors":[ 10 | ] 11 | } -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | src/app/code/community/Hackathon/ChatConnector app/code/community/Hackathon/ChatConnector 2 | src/app/etc/modules/Hackathon_ChatConnector.xml app/etc/modules/Hackathon_ChatConnector.xml 3 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Helper/Data.php: -------------------------------------------------------------------------------- 1 | getNode('chatconnector/connectors'.$key); 65 | 66 | return $connectors->asArray(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Connectors/Abstract.php: -------------------------------------------------------------------------------- 1 | , Marcel Hauri 25 | */ 26 | abstract class Hackathon_ChatConnector_Model_Connectors_Abstract 27 | implements Hackathon_ChatConnector_Model_Connectors_Interface 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Connectors/HipChat.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Connectors_HipChat 27 | extends Hackathon_ChatConnector_Model_Connectors_Abstract 28 | { 29 | const CODE = 'hipchat'; 30 | 31 | /** 32 | * Send the notification for the given connector. 33 | * 34 | * @param array $params Params 35 | * 36 | * @return bool 37 | * 38 | * @see https://www.hipchat.com/docs/apiv2/method/send_room_notification 39 | */ 40 | public function notify($params = array()) 41 | { 42 | $config = $this->getConfig(); 43 | 44 | $url = sprintf('http://api.hipchat.com/v2/room/%d/notification?auth_token=%s', 45 | intval($config['room_id']), 46 | $config['access_token'] 47 | ); 48 | 49 | $ch = curl_init(); 50 | curl_setopt($ch, CURLOPT_URL, $url); 51 | curl_setopt($ch, CURLOPT_NOBODY, 0); 52 | curl_setopt($ch, CURLOPT_HEADER, 0); 53 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); 54 | curl_setopt($ch, CURLOPT_POST, 1); 55 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); 56 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); 57 | curl_exec($ch); 58 | 59 | $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 60 | curl_close($ch); 61 | 62 | if (intval($status) === 204) { 63 | return true; 64 | } 65 | 66 | return false; 67 | } 68 | 69 | /** 70 | * Retrieve the connector config. 71 | * 72 | * @param null $store Store 73 | * 74 | * @return array 75 | */ 76 | public function getConfig($store = null) 77 | { 78 | return array( 79 | 'access_token' => Mage::getStoreConfig('hackathon_chatconnector/hipchat/access_token', $store), 80 | 'room_id' => Mage::getStoreConfig('hackathon_chatconnector/hipchat/room_id', $store), 81 | ); 82 | } 83 | 84 | /** 85 | * Retrieve the connector code. 86 | * 87 | * @return string 88 | */ 89 | public function getCode() 90 | { 91 | return self::CODE; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Connectors/Interface.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | interface Hackathon_ChatConnector_Model_Connectors_Interface 27 | { 28 | /** 29 | * Send the notification for the given connector. 30 | * 31 | * @param array $params Params 32 | * 33 | * @return bool 34 | */ 35 | public function notify($params = array()); 36 | 37 | /** 38 | * Retrieve the connector config. 39 | * 40 | * @param null $store Store 41 | * 42 | * @return array 43 | */ 44 | public function getConfig($store = null); 45 | 46 | /** 47 | * Retrieve the connector code. 48 | * 49 | * @return string 50 | */ 51 | public function getCode(); 52 | } 53 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Connectors/Slack.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Connectors_Slack 27 | extends Hackathon_ChatConnector_Model_Connectors_Abstract 28 | { 29 | const CODE = 'slack'; 30 | 31 | /** 32 | * Send the notification for the given connector. 33 | * 34 | * @param array $params Params 35 | * 36 | * @return bool 37 | */ 38 | public function notify($params = array()) 39 | { 40 | $config = $this->getConfig(); 41 | 42 | $ch = curl_init(); 43 | curl_setopt($ch, CURLOPT_URL, $config['webhook_url']); 44 | curl_setopt($ch, CURLOPT_NOBODY, 0); 45 | curl_setopt($ch, CURLOPT_HEADER, 0); 46 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 47 | curl_setopt($ch, CURLOPT_POST, 1); 48 | curl_setopt($ch, CURLOPT_POSTFIELDS, array('payload' => json_encode(array( 49 | 'text' => $params['message'], 50 | 'channel' => $config['channel'], 51 | 'username' => $config['username'], 52 | 'icon_emoji' => $config['icon'], 53 | )))); 54 | curl_exec($ch); 55 | 56 | $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 57 | curl_close($ch); 58 | 59 | if (intval($status) === 200) { 60 | return true; 61 | } 62 | 63 | return false; 64 | } 65 | 66 | /** 67 | * Retrieve the connector config. 68 | * 69 | * @param null $store Store 70 | * 71 | * @return array 72 | */ 73 | public function getConfig($store = null) 74 | { 75 | return array( 76 | 'webhook_url' => Mage::getStoreConfig('hackathon_chatconnector/slack/webhook_url', $store), 77 | 'channel' => Mage::getStoreConfig('hackathon_chatconnector/slack/channel', $store), 78 | 'username' => Mage::getStoreConfig('hackathon_chatconnector/slack/username', $store), 79 | 'icon' => Mage::getStoreConfig('hackathon_chatconnector/slack/icon', $store), 80 | ); 81 | } 82 | 83 | /** 84 | * Retrieve the connector code. 85 | * 86 | * @return string 87 | */ 88 | public function getCode() 89 | { 90 | return self::CODE; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Cron/Abstract.php: -------------------------------------------------------------------------------- 1 | getHelper()->getConfiguredConnectors($code); 28 | if (!$connectorConfig) { 29 | return false; 30 | } 31 | 32 | /* @var $connector Hackathon_ChatConnector_Model_Connectors_Interface */ 33 | $connector = Mage::getModel($connectorConfig['class']); 34 | if (!$connector) { 35 | return false; 36 | } 37 | 38 | return $connector; 39 | } 40 | 41 | /** 42 | * Retrieve the helper. 43 | * 44 | * @return Hackathon_ChatConnector_Helper_Data 45 | */ 46 | public function getHelper() 47 | { 48 | if (null === $this->_helper) { 49 | $this->setHelper(Mage::helper('hackathon_chatconnector')); 50 | } 51 | 52 | return $this->_helper; 53 | } 54 | 55 | /** 56 | * Set the helper. 57 | * 58 | * @param Hackathon_ChatConnector_Helper_Data $helper Helper 59 | */ 60 | public function setHelper($helper) 61 | { 62 | $this->_helper = $helper; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Cron/Cleanup.php: -------------------------------------------------------------------------------- 1 | getHelper()->isActive()) { 15 | return; 16 | } 17 | 18 | /* @var $queueResource Hackathon_ChatConnector_Model_Resource_Queue */ 19 | $queueResource = Mage::getResourceModel('hackathon_chatconnector/queue'); 20 | $queueResource->cleanupProcessedEntries(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Cron/Process.php: -------------------------------------------------------------------------------- 1 | getHelper()->isActive()) { 15 | return; 16 | } 17 | 18 | $connectors = $this->getHelper()->getActiveConnectors(); 19 | foreach ($connectors as $connectorCode) { 20 | /* @var $connector Hackathon_ChatConnector_Model_Connectors_Interface */ 21 | $connector = $this->getConnectorByCode($connectorCode); 22 | if (!$connector) { 23 | continue; 24 | } 25 | 26 | $this->_processQueue($connector); 27 | } 28 | } 29 | 30 | /** 31 | * Process the queue for the given connector. 32 | * 33 | * @param Hackathon_ChatConnector_Model_Connectors_Interface $connector Connector 34 | */ 35 | protected function _processQueue(Hackathon_ChatConnector_Model_Connectors_Interface $connector) 36 | { 37 | $retryFreq = $this->getHelper()->getRetryFrequency(); 38 | 39 | /* @var $collection Hackathon_ChatConnector_Model_Resource_Queue_Collection */ 40 | $collection = Mage::getResourceModel('hackathon_chatconnector/queue_collection'); 41 | $collection->addConnectorFilter($connector->getCode()); 42 | $collection->getSelect()->where(' 43 | `status` = '.Hackathon_ChatConnector_Model_Queue::STATUS_PENDING.' 44 | OR ( 45 | `status` = '.Hackathon_ChatConnector_Model_Queue::STATUS_FAILED." 46 | AND `updated_at` <= '".Mage::getModel('core/date')->date(null, time() - $retryFreq)."' 47 | )"); 48 | 49 | // Check if there are messsages to process 50 | if (!$collection->count()) { 51 | return; 52 | } 53 | 54 | // Iterate over items and try sending them 55 | $successIds = array(); 56 | $failIds = array(); 57 | foreach ($collection as $queueItem) { 58 | /* @var $queueItem Hackathon_ChatConnector_Model_Queue */ 59 | 60 | $params = json_decode($queueItem->getData('message_params'), true); 61 | 62 | $result = $connector->notify($params); 63 | if (true === $result) { 64 | $successIds[] = $queueItem->getId(); 65 | } else { 66 | $failIds[] = $queueItem->getId(); 67 | } 68 | } 69 | 70 | /* @var $queueResource Hackathon_ChatConnector_Model_Resource_Queue */ 71 | $queueResource = Mage::getResourceModel('hackathon_chatconnector/queue'); 72 | 73 | // Update the successful items 74 | if (count($successIds)) { 75 | $queueResource->updateStatus($successIds, Hackathon_ChatConnector_Model_Queue::STATUS_PROCESSED); 76 | } 77 | 78 | // Update the failed items 79 | if (count($failIds)) { 80 | $queueResource->updateStatus($failIds, Hackathon_ChatConnector_Model_Queue::STATUS_FAILED); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Abstract.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | abstract class Hackathon_ChatConnector_Model_Events_Abstract 27 | implements Hackathon_ChatConnector_Model_Events_Interface 28 | { 29 | /** 30 | * @var Hackathon_ChatConnector_Helper_Data 31 | */ 32 | protected $_helper = null; 33 | 34 | /** 35 | * Add the item to the queue. 36 | * 37 | * @param string $message Message 38 | * @param array $params Additional Params 39 | */ 40 | protected function _addQueueItem($message, $params = array()) 41 | { 42 | if (!$this->getHelper()->isActive()) { 43 | return; 44 | } 45 | 46 | $params = array_merge(array('message' => $message), $params); 47 | 48 | $serializedParams = json_encode((array) $params); 49 | $connectors = $this->getHelper()->getActiveConnectors(); 50 | 51 | foreach ($connectors as $code) { 52 | $connectorParams = $this->getHelper()->getConfiguredConnectors($code); 53 | 54 | /* @var $connector Hackathon_ChatConnector_Model_Connectors_Interface */ 55 | $connector = Mage::getModel($connectorParams['class']); 56 | if (!$connector) { 57 | continue; 58 | } 59 | 60 | /* @var $queueItem Hackathon_ChatConnector_Model_Queue */ 61 | $queueItem = Mage::getModel('hackathon_chatconnector/queue')->setData(array( 62 | 'message_params' => $serializedParams, 63 | 'connector' => $connector->getCode(), 64 | )); 65 | 66 | try { 67 | $queueItem->save(); 68 | } catch (Exception $e) { 69 | Mage::logException($e); 70 | } 71 | } 72 | } 73 | 74 | /** 75 | * Retrieve the helper. 76 | * 77 | * @return Hackathon_ChatConnector_Helper_Data 78 | */ 79 | public function getHelper() 80 | { 81 | if (null === $this->_helper) { 82 | $this->setHelper(Mage::helper('hackathon_chatconnector')); 83 | } 84 | 85 | return $this->_helper; 86 | } 87 | 88 | /** 89 | * Set the helper. 90 | * 91 | * @param Hackathon_ChatConnector_Helper_Data $helper Helper 92 | */ 93 | public function setHelper($helper) 94 | { 95 | $this->_helper = $helper; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Customer/Register.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Events_Customer_Register 27 | extends Hackathon_ChatConnector_Model_Events_Abstract 28 | { 29 | /** 30 | * Listen to customer register success event. 31 | * 32 | * @param Varien_Event_Observer $observer Observer 33 | */ 34 | public function listener(Varien_Event_Observer $observer) 35 | { 36 | $customer = $observer->getEvent()->getCustomer(); 37 | $helper = $this->getHelper(); 38 | 39 | $messageTemplate = $helper->__('%1$s %2$s has created an account in store view: %3$s', 40 | $customer->getFirstname(), 41 | $customer->getLastname(), 42 | $customer->getCreatedIn() 43 | ); 44 | 45 | $this->_addQueueItem($messageTemplate); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Interface.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | interface Hackathon_ChatConnector_Model_Events_Interface 27 | { 28 | /** 29 | * Listener for the specified observer. 30 | * 31 | * @param Varien_Event_Observer $observer Observer 32 | */ 33 | public function listener(Varien_Event_Observer $observer); 34 | } 35 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Newsletter/Subscriber.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Events_Newsletter_Subscriber 27 | extends Hackathon_ChatConnector_Model_Events_Abstract 28 | { 29 | /** 30 | * Listen to a newsletter subscription. 31 | * 32 | * @param Varien_Event_Observer $observer Observer 33 | */ 34 | public function listener(Varien_Event_Observer $observer) 35 | { 36 | // TODO: Implement listener() method. 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Sales/Invoice.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Events_Sales_Invoice 27 | extends Hackathon_ChatConnector_Model_Events_Abstract 28 | { 29 | /** 30 | * Listen to invoice creation. 31 | * 32 | * @param Varien_Event_Observer $observer Observer 33 | */ 34 | public function listener(Varien_Event_Observer $observer) 35 | { 36 | if (!Mage::getStoreConfigFlag('hackathon_chatconnector/notifications/new_invoice')) { 37 | return $this; 38 | } 39 | 40 | $order = $observer->getEvent()->getOrder(); 41 | $shippingObj = $order->getShippingAddress(); 42 | $street = implode(' ', (array) $shippingObj->getStreet()); 43 | 44 | $messageTemplate = "New Invoice 45 | Shipping to 46 | {$shippingObj->getFirstname()} {$shippingObj->getLastname()} 47 | {$street} 48 | {$shippingObj->getPostcode()} {$shippingObj->getCity()} {$shippingObj->getPostcode()} ({$shippingObj->getCountryId()}) 49 | 50 | Items 51 | "; 52 | 53 | foreach ($order->getAllVisibleItems() as $_item) { 54 | $qty = (int) $_item->getQtyOrdered(); 55 | $messageTemplate .= "{$qty}x {$_item->getName()} ({$_item->getSku()})\n"; 56 | } 57 | 58 | $this->_addQueueItem($messageTemplate); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Events/Sales/Order.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Events_Sales_Order 27 | extends Hackathon_ChatConnector_Model_Events_Abstract 28 | { 29 | 30 | /** 31 | * Listen to order cancel payment event 32 | * 33 | * @param Varien_Event_Observer $event 34 | * 35 | * @return mixed|void 36 | */ 37 | public function listener(Varien_Event_Observer $event) 38 | { 39 | $itemTemplate = ''; 40 | $orderIds = $event->getOrderIds(); 41 | $helper = $this->getHelper(); 42 | 43 | $items = Mage::getModel('sales/order_item') 44 | ->getCollection() 45 | ->addFieldToFilter('order_id', array('in' => $orderIds)) 46 | ->getItems(); 47 | 48 | foreach ($items as $item) { 49 | $itemTemplate .= "{$item->getName()} ({$item->getSku()}) : {$item->getPrice()}"; 50 | } 51 | 52 | $this->_addQueueItem($helper->__('A new order was placed: %1$s', $itemTemplate)); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Queue.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Queue extends Mage_Core_Model_Abstract 27 | { 28 | const STATUS_PENDING = 1; 29 | const STATUS_PROCESSED = 2; 30 | const STATUS_FAILED = 3; 31 | 32 | /** 33 | * Init the resource model. 34 | */ 35 | public function _construct() 36 | { 37 | parent::_construct(); 38 | $this->_init('hackathon_chatconnector/queue'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Resource/Queue.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Resource_Queue extends Mage_Core_Model_Resource_Db_Abstract 27 | { 28 | /** 29 | * Init the main table and primary key field. 30 | */ 31 | public function _construct() 32 | { 33 | $this->_init('hackathon_chatconnector/queue', 'entity_id'); 34 | } 35 | 36 | /** 37 | * _beforeSave. 38 | * 39 | * @param Mage_Core_Model_Abstract $object 40 | * 41 | * @return Mage_Core_Model_Resource_Db_Abstract 42 | */ 43 | protected function _beforeSave(Mage_Core_Model_Abstract $object) 44 | { 45 | $object->setUpdatedAt($this->formatDate(true)); 46 | if ($object->isObjectNew()) { 47 | $object->setCreatedAt($this->formatDate(true)); 48 | } 49 | 50 | $status = $object->getStatus(); 51 | if ($object->isObjectNew() && empty($status)) { 52 | $object->setStatus(Hackathon_ChatConnector_Model_Queue::STATUS_PENDING); 53 | } 54 | 55 | return parent::_beforeSave($object); 56 | } 57 | 58 | /** 59 | * Update the given queue items with the given status. 60 | * 61 | * @param array $entityIds Entity IDs 62 | * @param int $status Status 63 | */ 64 | public function updateStatus($entityIds, $status) 65 | { 66 | if (!is_array($entityIds)) { 67 | $entityIds = array($entityIds); 68 | } 69 | 70 | $adapter = $this->_getWriteAdapter(); 71 | $bind = array( 72 | 'status' => $status, 73 | 'updated_at' => Mage::getModel('core/date')->gmtDate(), 74 | ); 75 | $where = array( 76 | 'entity_id IN(?)' => $entityIds, 77 | ); 78 | $adapter->update($this->getMainTable(), $bind, $where); 79 | } 80 | 81 | /** 82 | * Update all non-processed rma entries to processed. 83 | */ 84 | public function cleanupProcessedEntries() 85 | { 86 | $adapter = $this->_getWriteAdapter(); 87 | $where = array('status = ?' => Hackathon_ChatConnector_Model_Queue::STATUS_PROCESSED); 88 | $adapter->delete($this->getMainTable(), $where); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Resource/Queue/Collection.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Resource_Queue_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract 27 | { 28 | /** 29 | * Init collection model. 30 | */ 31 | protected function _construct() 32 | { 33 | parent::_construct(); 34 | $this->_init('hackathon_chatconnector/queue'); 35 | } 36 | 37 | /** 38 | * Filter the collection by the connector code. 39 | * 40 | * @param string $connector Connector 41 | * 42 | * @return Hackathon_ChatConnector_Model_Resource_Queue_Collection 43 | */ 44 | public function addConnectorFilter($connector) 45 | { 46 | $this->getSelect()->where('connector = ?', $connector); 47 | 48 | return $this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/Resource/Setup.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_Resource_Setup 27 | extends Mage_Core_Model_Resource_Setup 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Model/System/Config/Source/Dropdown/Connectors.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Hackathon_ChatConnector_Model_System_Config_Source_Dropdown_Connectors 27 | { 28 | /** 29 | * Retrieve the configured connectors. 30 | * 31 | * @return array 32 | */ 33 | public function toOptionArray() 34 | { 35 | $values = array(); 36 | $connectors = Mage::helper('hackathon_chatconnector')->getConfiguredConnectors(); 37 | foreach ($connectors as $key => $params) { 38 | $values[] = array( 39 | 'value' => $key, 40 | 'label' => $params['name'], 41 | ); 42 | } 43 | 44 | return $values; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Config/Config.php: -------------------------------------------------------------------------------- 1 | assertModuleVersion($this->expected('module')->getVersion()); 17 | $this->assertModuleCodePool($this->expected('module')->getCodePool()); 18 | $this->assertSetupResourceDefined(null, 'hackathon_chatconnector_setup'); 19 | $this->assertSetupResourceExists(null, 'hackathon_chatconnector_setup'); 20 | $this->assertSetupScriptVersions(); 21 | $this->assertTableAlias('hackathon_chatconnector/queue', 'hackathon_chatconnector_queue'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Config/Config/expectations/globalConfig.yaml: -------------------------------------------------------------------------------- 1 | module: 2 | version: 1.0.0 3 | code_pool: community 4 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data.php: -------------------------------------------------------------------------------- 1 | _helper = Mage::helper('hackathon_chatconnector'); 22 | } 23 | 24 | /** 25 | * @test 26 | * @loadFixture 27 | */ 28 | public function testIsActive() 29 | { 30 | $this->assertTrue($this->_helper->isActive()); 31 | } 32 | 33 | /** 34 | * @test 35 | * @loadFixture 36 | */ 37 | public function testIsNotActive() 38 | { 39 | $this->assertFalse($this->_helper->isActive()); 40 | } 41 | 42 | /** 43 | * @test 44 | * @loadFixture 45 | * @loadExpectations 46 | */ 47 | public function getActiveConnectors() 48 | { 49 | $this->assertEquals( 50 | $this->expected('connectors')->getResult(), 51 | $this->_helper->getActiveConnectors() 52 | ); 53 | } 54 | 55 | /** 56 | * @test 57 | * @loadFixture 58 | */ 59 | public function getRetryFrequency() 60 | { 61 | $this->assertEquals(7200, $this->_helper->getRetryFrequency()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data/_data/ex-getActiveConnectors.yaml: -------------------------------------------------------------------------------- 1 | connectors: 2 | result: 3 | - slack 4 | - hipchat 5 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data/_data/fx-getActiveConnectors.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | default/hackathon_chatconnector/general/connectors: slack,hipchat 3 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data/_data/fx-getRetryFrequency.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | default/hackathon_chatconnector/general/retry_frequency: 7200 3 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data/_data/fx-testIsActive.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | default/hackathon_chatconnector/general/enabled: 1 3 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Helper/Data/_data/fx-testIsNotActive.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | default/hackathon_chatconnector/general/enabled: 0 3 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Model/Resource/Queue.php: -------------------------------------------------------------------------------- 1 | _model = Mage::getResourceModel('hackathon_chatconnector/queue'); 17 | } 18 | 19 | /** 20 | * @loadFixture 21 | * @dataProvider dataProvider 22 | */ 23 | public function testUpdateStatus($entityIds) 24 | { 25 | // Test update 26 | $this->_model->updateStatus($entityIds, Hackathon_ChatConnector_Model_Queue::STATUS_PROCESSED); 27 | 28 | // Check result 29 | if (!is_array($entityIds)) { 30 | $entityIds = array($entityIds); 31 | } 32 | 33 | $collection = Mage::getResourceModel('hackathon_chatconnector/queue_collection'); 34 | $collection->addFieldToFilter('entity_id', array('in' => $entityIds)); 35 | $this->assertEquals(count($entityIds), $collection->count()); 36 | foreach ($collection as $item) { 37 | $this->assertEquals(2, $item->getData('status')); 38 | } 39 | } 40 | 41 | /** 42 | * @loadFixture 43 | */ 44 | public function testCleanupProcessedEntries() 45 | { 46 | $this->_model->cleanupProcessedEntries(); 47 | 48 | $collection = Mage::getResourceModel('hackathon_chatconnector/queue_collection'); 49 | $this->assertEquals(0, $collection->count()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Model/Resource/Queue/_data/dp-testUpdateStatus.yaml: -------------------------------------------------------------------------------- 1 | test1: 2 | entityIds: 1 3 | test2: 4 | entityIds: 5 | - 2 6 | - 3 7 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Model/Resource/Queue/_data/fx-testCleanupProcessedEntries.yaml: -------------------------------------------------------------------------------- 1 | tables: 2 | hackathon_chatconnector/queue: 3 | - entity_id: 1 4 | connector: slack 5 | message_params: LOREM IPSUM 6 | created_at: 2015-05-29 14:00:00 7 | updated_at: 2015-05-29 14:00:00 8 | status: 2 9 | - entity_id: 2 10 | connector: slack 11 | message_params: LOREM IPSUM 12 | created_at: 2015-05-29 14:00:00 13 | updated_at: 2015-05-29 14:00:00 14 | status: 2 15 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/Test/Model/Resource/Queue/_data/fx-testUpdateStatus.yaml: -------------------------------------------------------------------------------- 1 | tables: 2 | hackathon_chatconnector/queue: 3 | - entity_id: 1 4 | connector: slack 5 | message_params: LOREM IPSUM 6 | created_at: 2015-05-29 14:00:00 7 | updated_at: 2015-05-29 14:00:00 8 | status: 1 9 | - entity_id: 2 10 | connector: slack 11 | message_params: LOREM IPSUM 12 | created_at: 2015-05-29 14:00:00 13 | updated_at: 2015-05-29 14:00:00 14 | status: 1 15 | - entity_id: 3 16 | connector: slack 17 | message_params: LOREM IPSUM 18 | created_at: 2015-05-29 14:00:00 19 | updated_at: 2015-05-29 14:00:00 20 | status: 1 21 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/etc/adminhtml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Hackathon Chat Connector 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1.0.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Hackathon_ChatConnector_Model_Events_Customer_Register 14 | listener 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Hackathon_ChatConnector_Model_Events_Sales_Order 23 | listener 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Hackathon_ChatConnector_Model_Events_Transactional_Invoice 32 | listener 33 | 34 | 35 | 36 | 37 | 47 | 48 | 49 | 50 | Hackathon_ChatConnector_Block 51 | 52 | 53 | 54 | 55 | Hackathon_ChatConnector_Helper 56 | 57 | 58 | 59 | 60 | Hackathon_ChatConnector_Model 61 | hackathon_chatconnector_resource 62 | 63 | 64 | Hackathon_ChatConnector_Model_Resource 65 | 66 | 67 | hackathon_chatconnector_queue
68 |
69 |
70 |
71 |
72 | 73 | 74 | 75 | Hackathon_ChatConnector 76 | Hackathon_ChatConnector_Model_Resource_Setup 77 | 78 | 79 | 80 |
81 | 82 | 83 | 84 | 85 | hackathon_chatconnector/general/cron_expr_process 86 | 87 | 88 | hackathon_chatconnector/cron_process::run 89 | 90 | 91 | 92 | 93 | hackathon_chatconnector/general/cron_expr_cleanup 94 | 95 | 96 | hackathon_chatconnector/cron_cleanup::run 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Slack 112 | Hackathon_ChatConnector_Model_Connectors_Slack 113 | 114 | 115 | HipChat 116 | Hackathon_ChatConnector_Model_Connectors_HipChat 117 | 118 | 119 | 120 | 121 | 122 | 123 | 7200 124 | */5 * * * * 125 | 0 2 * * * 126 | 127 | 128 | 129 |
130 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | separator-top 6 | 7 | service 8 | text 9 | 10 10 | 1 11 | 0 12 | 0 13 | 14 | 15 | 16 | text 17 | 10 18 | 1 19 | 0 20 | 0 21 | 22 | 23 | 24 | select 25 | adminhtml/system_config_source_yesno 26 | 1 27 | 1 28 | 0 29 | 0 30 | 31 | 32 | 33 | multiselect 34 | hackathon_chatconnector/system_config_source_dropdown_connectors 35 | 2 36 | 1 37 | 0 38 | 0 39 | 40 | 1 41 | 42 | 43 | 44 | 45 | 46 | text 47 | 3 48 | 1 49 | 0 50 | 0 51 | 52 | 1 53 | 54 | 55 | 56 | 57 | 58 | text 59 | 4 60 | 1 61 | 0 62 | 0 63 | 64 | 1 65 | 66 | 67 | 68 | 69 | 70 | text 71 | 5 72 | 1 73 | 0 74 | 0 75 | 76 | 1 77 | 78 | 79 | 80 | 81 | 82 | 83 | text 84 | 20 85 | 1 86 | 0 87 | 0 88 | 89 | 90 | 91 | text 92 | 30 93 | 1 94 | 0 95 | 1 96 | 97 | 98 | 99 | text 100 | 40 101 | 1 102 | 0 103 | 1 104 | 105 | 106 | 107 | text 108 | 50 109 | 1 110 | 0 111 | 1 112 | 113 | 114 | 115 | text 116 | 60 117 | For more informations see: https://my.slack.com/customize/emoji 118 | 1 119 | 0 120 | 1 121 | 122 | 123 | 124 | 125 | 126 | text 127 | 30 128 | 1 129 | 0 130 | 0 131 | 132 | 133 | 134 | text 135 | 30 136 | 1 137 | 0 138 | 1 139 | 140 | 141 | 142 | text 143 | 40 144 | 1 145 | 0 146 | 1 147 | 148 | 149 | 150 | 151 | 152 | text 153 | 100 154 | 1 155 | 0 156 | 0 157 | 158 | 159 | 160 | select 161 | adminhtml/system_config_source_yesno 162 | 10 163 | 1 164 | 0 165 | 1 166 | 167 | 168 | 169 | select 170 | adminhtml/system_config_source_yesno 171 | 15 172 | 1 173 | 0 174 | 1 175 | 176 | 177 | 178 | select 179 | adminhtml/system_config_source_yesno 180 | 10 181 | 1 182 | 0 183 | 1 184 | 185 | 186 | 187 | select 188 | adminhtml/system_config_source_yesno 189 | 20 190 | 1 191 | 0 192 | 1 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /src/app/code/community/Hackathon/ChatConnector/sql/hackathon_chatconnector_setup/install-1.0.0.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | 26 | /* @var $installer Mage_Core_Model_Resource_Setup */ 27 | $installer = $this; 28 | $installer->startSetup(); 29 | 30 | $table = $installer->getConnection() 31 | ->newTable($installer->getTable('hackathon_chatconnector/queue')) 32 | ->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( 33 | 'identity' => true, 34 | 'unsigned' => true, 35 | 'nullable' => false, 36 | 'primary' => true, 37 | ), 'Message Id') 38 | ->addColumn('connector', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array( 39 | 'nullable' => false, 40 | ), 'Message Parameters') 41 | ->addColumn('message_params', Varien_Db_Ddl_Table::TYPE_TEXT, null, array( 42 | 'nullable' => false, 43 | 'default' => '', 44 | ), 'Message Parameters') 45 | ->addColumn('created_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( 46 | 'nullable' => true, 47 | ), 'Created At') 48 | ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( 49 | 'nullable' => true, 50 | ), 'Updated At') 51 | ->addColumn('status', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array( 52 | ), 'Enabled') 53 | ->setComment('Message Queue'); 54 | 55 | $installer->getConnection()->createTable($table); 56 | 57 | $installer->endSetup(); 58 | -------------------------------------------------------------------------------- /src/app/etc/modules/Hackathon_ChatConnector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------