name = 'referralprogram'; $this->tab = 'Tools'; $this->version = '1.4'; parent::__construct(); $this->confirmUninstall = $this->l('All sponsor and friends would be deleted. Do you really want to uninstall this module ?'); $this->displayName = $this->l('Customer referral program'); $this->description = $this->l('Integrate a referral program system to your shop.'); $this->_configuration = Configuration::getMultiple(array( 'REFERRAL_NB_FRIENDS', 'REFERRAL_ORDER_QUANTITY', 'REFERRAL_DISCOUNT_TYPE', 'REFERRAL_DISCOUNT_VALUE' )); $this->_configuration['REFERRAL_DISCOUNT_DESCRIPTION'] = Configuration::getInt('REFERRAL_DISCOUNT_DESCRIPTION'); $path = dirname(__FILE__); if (strpos(__FILE__, 'Module.php') !== false) $path .= '/../modules/'.$this->name; $this->_xmlFile = $path.'/referralprogram.xml'; include_once($path.'/ReferralProgramModule.php'); } public function install() { $langs = Language::getLanguages(false); foreach ($langs AS $lang) $desc[$lang['id_lang']] = 'ReferralProgram'; if (!parent::install() OR !$this->installDB() OR !Configuration::updateValue('REFERRAL_DISCOUNT_DESCRIPTION', $desc) OR !Configuration::updateValue('REFERRAL_ORDER_QUANTITY', 1) OR !Configuration::updateValue('REFERRAL_DISCOUNT_TYPE', 2) OR !Configuration::updateValue('REFERRAL_NB_FRIENDS', 5) OR !$this->registerHook('shoppingCart') OR !$this->registerHook('orderConfirmation') OR !$this->registerHook('updateOrderStatus') OR !$this->registerHook('adminCustomers') OR !$this->registerHook('createAccount') OR !$this->registerHook('createAccountForm') OR !$this->registerHook('customerAccount') ) return false; foreach (Currency::getCurrencies() as $currency) Configuration::updateValue('REFERRAL_DISCOUNT_VALUE_'.intval($currency['id_currency']), 5); /* This hook is optional */ $this->registerHook('myAccountBlock'); return true; } public function installDB() { return Db::getInstance()->Execute(' CREATE TABLE `'._DB_PREFIX_.'referralprogram` ( `id_referralprogram` INT UNSIGNED NOT NULL AUTO_INCREMENT, `id_sponsor` INT UNSIGNED NOT NULL, `email` VARCHAR(255) NOT NULL, `lastname` VARCHAR(128) NOT NULL, `firstname` VARCHAR(128) NOT NULL, `id_customer` INT UNSIGNED DEFAULT NULL, `id_discount` INT UNSIGNED DEFAULT NULL, `id_discount_sponsor` INT UNSIGNED DEFAULT NULL, `date_add` DATETIME NOT NULL, `date_upd` DATETIME NOT NULL, PRIMARY KEY (`id_referralprogram`), UNIQUE KEY `index_unique_referralprogram_email` (`email`) ) DEFAULT CHARSET=utf8 ;'); } public function uninstall() { if (!parent::uninstall() OR !$this->uninstallDB() OR !$this->removeMail() ) return false; return true; } public function uninstallDB() { return Db::getInstance()->Execute('DROP TABLE `'._DB_PREFIX_.'referralprogram`;'); } public function removeMail() { $langs = Language::getLanguages(false); foreach ($langs as $lang) foreach ($this->_mails['name'] as $name) foreach ($this->_mails['ext'] as $ext) { $file = _PS_MAIL_DIR_.$lang['iso_code'].'/'.$name.'.'.$ext; if (file_exists($file) AND !@unlink($file)) $this->_errors[] = $this->l('Cannot delete this file:').' '.$file; } return true; } private function _postProcess() { Configuration::updateValue('REFERRAL_ORDER_QUANTITY', intval(Tools::getValue('order_quantity'))); foreach (Tools::getValue('discount_value') as $id_currency => $discount_value) Configuration::updateValue('REFERRAL_DISCOUNT_VALUE_'.intval($id_currency), floatval($discount_value)); Configuration::updateValue('REFERRAL_DISCOUNT_TYPE', intval(Tools::getValue('discount_type'))); Configuration::updateValue('REFERRAL_NB_FRIENDS', intval(Tools::getValue('nb_friends'))); Configuration::updateValue('REFERRAL_DISCOUNT_DESCRIPTION', Tools::getValue('discount_description')); $this->_html .= $this->displayConfirmation($this->l('Configuration updated.')); } private function _postValidation() { $this->_errors = array(); if (!intval(Tools::getValue('order_quantity')) OR Tools::getValue('order_quantity') < 0) $this->_errors[] = $this->displayError($this->l('Order quantity is required/invalid.')); if (!is_array(Tools::getValue('discount_value'))) $this->_errors[] = $this->displayError($this->l('Discount value is invalid.')); foreach (Tools::getValue('discount_value') as $id_currency => $discount_value) if ($discount_value == '') $this->_errors[] = $this->displayError($this->l('Discount value for the currency #').$id_currency.$this->l(' is empty.')); elseif (!Validate::isUnsignedFloat($discount_value)) $this->_errors[] = $this->displayError($this->l('Discount value for the currency #').$id_currency.$this->l(' is invalid.')); if (!intval(Tools::getValue('discount_type')) OR Tools::getValue('discount_type') < 1 OR Tools::getValue('discount_type') > 2) $this->_errors[] = $this->displayError($this->l('Discount type is required/invalid.')); if (!intval(Tools::getValue('nb_friends')) OR Tools::getValue('nb_friends') < 0) $this->_errors[] = $this->displayError($this->l('Number of friends is required/invalid.')); } private function _writeXml() { $forbiddenKey = array('submitUpdate'); // Forbidden key // Generate new XML data $newXml = '<'.'?xml version=\'1.0\' encoding=\'utf-8\' ?>'."\n"; $newXml .= ''."\n"; $newXml .= "\t".''; // Making body data foreach ($_POST AS $key => $field) { if ($line = $this->putContent($newXml, $key, $field, $forbiddenKey, 'body')) $newXml .= $line; } $newXml .= "\n\t".''."\n"; $newXml .= ''."\n"; /* write it into the editorial xml file */ if ($fd = @fopen($this->_xmlFile, 'w')) { if (!@fwrite($fd, $newXml)) $this->_html .= $this->displayError($this->l('Unable to write to the xml file.')); if (!@fclose($fd)) $this->_html .= $this->displayError($this->l('Can\'t close the xml file.')); } else $this->_html .= $this->displayError($this->l('Unable to update the xml file. Please check the xml file\'s writing permissions.')); } public function putContent($xml_data, $key, $field, $forbidden, $section) { foreach ($forbidden AS $line) if ($key == $line) return 0; if (!preg_match('/^'.$section.'_/i', $key)) return 0; $key = preg_replace('/^'.$section.'_/i', '', $key); $field = Tools::htmlentitiesDecodeUTF8(htmlspecialchars($field)); if (!$field) return 0; return ("\n\t\t".'<'.$key.'>'); } public function getContent() { if (Tools::isSubmit('submitReferralProgram')) { $this->_postValidation(); if (!sizeof($this->_errors)) $this->_postProcess(); else foreach ($this->_errors AS $err) $this->_html .= '
'.$err.'
'; } elseif (Tools::isSubmit('submitText')) { foreach ($_POST AS $key => $value) if (!Validate::isString(Tools::getValue($key))) { $this->_html .= $this->displayError($this->l('Invalid html field, javascript is forbidden')); $this->_displayForm(); return $this->_html; } $this->_writeXml(); } $this->_html .= '

'.$this->displayName.'

'; $this->_displayForm(); $this->_displayFormRules(); return $this->_html; } private function _displayForm() { $divLangName = 'cpara¤dd'; $currencies = Currency::getCurrencies(); $this->_html .= '
'.$this->l('Settings').''.$this->l('Settings').'

 

'; foreach ($currencies as $currency) $this->_html .= '

'; $this->_html .= '

'; $defaultLanguage = intval(Configuration::get('PS_LANG_DEFAULT')); $languages = Language::getLanguages(); foreach ($languages as $language) $this->_html .= '
'; $this->_html .= $this->displayFlags($languages, $defaultLanguage, $divLangName, 'dd', true); $this->_html .= '


'; } private function _displayFormRules() { global $cookie; // Languages preliminaries $defaultLanguage = intval(Configuration::get('PS_LANG_DEFAULT')); $languages = Language::getLanguages(); $iso = Language::getIsoById($defaultLanguage); $divLangName = 'cpara¤dd'; // xml loading $xml = false; if (file_exists($this->_xmlFile)) { if (!$xml = @simplexml_load_file($this->_xmlFile)) $this->_html .= $this->displayError($this->l('Your text is empty.')); } $this->_html .= '
'.$this->l('Referral program rules').''; foreach ($languages as $language) { $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $defaultLanguage, $divLangName, 'cpara', true); $this->_html .= '
'; } /** * Hook call when cart created and updated * Display the discount name if the sponsor friend have one */ public function hookShoppingCart($params) { $cart = $params['cart']; if (!isset($cart->id_customer)) return false; if (!($id_referralprogram = ReferralProgramModule::isSponsorised(intval($cart->id_customer), true))) return false; $referralprogram = new ReferralProgramModule($id_referralprogram); if (!Validate::isLoadedObject($referralprogram)) return false; $discount = new Discount($referralprogram->id_discount); if (!Validate::isLoadedObject($discount)) return false; if ($cart->checkDiscountValidity($discount, $cart->getDiscounts(), $cart->getOrderTotal(true, 1), $cart->getProducts())===false) { global $smarty; $smarty->assign(array( 'discount_display' => Discount::display($discount->value, $discount->id_discount_type, new Currency($params['cookie']->id_currency)), 'discount' => $discount )); return $this->display(__FILE__, 'shopping-cart.tpl'); } return false; } /** * Hook display on customer account page * Display an additional link on my-account and block my-account */ public function hookCustomerAccount($params) { return $this->display(__FILE__, 'my-account.tpl'); } public function hookMyAccountBlock($params) { return $this->hookCustomerAccount($params); } /** * Hook display on form create account * Add an additional input on bottom for fill the sponsor's e-mail address */ public function hookCreateAccountForm($params) { global $smarty; $blowfish = new Blowfish(_COOKIE_KEY_, _COOKIE_IV_); $explodeResult = explode('|', $blowfish->decrypt(urldecode(Tools::getValue('sponsor')))); if ($explodeResult AND count($explodeResult) > 1 AND list($id_referralprogram, $email) = $explodeResult AND intval($id_referralprogram) AND Validate::isEmail($email) AND $id_referralprogram == ReferralProgramModule::isEmailExists($email)) { $referralprogram = new ReferralProgramModule($id_referralprogram); if (Validate::isLoadedObject($referralprogram)) { /* hack for display referralprogram information in form */ $_POST['customer_firstname'] = $referralprogram->firstname; $_POST['firstname'] = $referralprogram->firstname; $_POST['customer_lastname'] = $referralprogram->lastname; $_POST['lastname'] = $referralprogram->lastname; $_POST['email'] = $referralprogram->email; $_POST['email_create'] = $referralprogram->email; $sponsor = new Customer($referralprogram->id_sponsor); $_POST['referralprogram'] = $sponsor->email; } } return $this->display(__FILE__, 'authentication.tpl'); } /** * Hook called on creation customer account * Create a discount for the customer if sponsorised */ public function hookCreateAccount($params) { global $cookie; $newCustomer = $params['newCustomer']; if (!Validate::isLoadedObject($newCustomer)) return false; $postVars = $params['_POST']; if (empty($postVars) OR !isset($postVars['referralprogram']) OR empty($postVars['referralprogram'])) return false; $sponsorEmail = $postVars['referralprogram']; if (!Validate::isEmail($sponsorEmail) OR $sponsorEmail == $newCustomer->email) return false; $sponsor = new Customer(); if ($sponsor = $sponsor->getByEmail($sponsorEmail)) { if ($id_referralprogram = ReferralProgramModule::isEmailExists($newCustomer->email, true, false)) { $referralprogram = new ReferralProgramModule($id_referralprogram); if ($referralprogram->id_sponsor == $sponsor->id) { $referralprogram->id_customer = $newCustomer->id; $referralprogram->save(); if ($referralprogram->registerDiscountForSponsored(intval($params['cookie']->id_currency))) { $discount = new Discount(intval($referralprogram->id_discount)); if (Validate::isLoadedObject($discount)) { $data = array( '{firstname}' => $newCustomer->firstname, '{lastname}' => $newCustomer->lastname, '{voucher_num}' => $discount->name, '{voucher_amount}' => Tools::displayPrice(floatval(Configuration::get('REFERRAL_DISCOUNT_VALUE_'.intval($cookie->id_currency))), intval(Configuration::get('PS_CURRENCY_DEFAULT')))); Mail::Send(intval($cookie->id_lang), 'referralprogram-voucher', $this->l('Congratulations!'), $data, $newCustomer->email, $newCustomer->firstname.' '.$newCustomer->lastname, strval(Configuration::get('PS_SHOP_EMAIL')), strval(Configuration::get('PS_SHOP_NAME')), NULL, NULL, dirname(__FILE__).'/mails/'); } } return true; } } } return false; } /** * Hook display in tab AdminCustomers on BO * Data table with all sponsors informations for a customer */ public function hookAdminCustomers($params) { $customer = new Customer(intval($params['id_customer'])); if (!Validate::isLoadedObject($customer)) die (Tools::displayError('Incorrect object Customer.')); global $cookie; $friends = ReferralProgramModule::getSponsorFriend($customer->id); if ($id_referralprogram = ReferralProgramModule::isSponsorised(intval($customer->id), true)) { $referralprogram = new ReferralProgramModule($id_referralprogram); $sponsor = new Customer($referralprogram->id_sponsor); } $html = '

'.$this->l('Referral program').'

'; // link to the detail of the sponsor $html.= '

'.(isset($sponsor) ? $this->l('Customer\'s sponsor:').' '.$sponsor->firstname.' '.$sponsor->lastname.'' : $this->l('No one has sponsored this customer.')).'

'; if ($friends AND sizeof($friends)) { $html.= '

'.sizeof($friends).' '.(sizeof($friends) > 1 ? $this->l('sponsored customers:') : $this->l('sponsored customer:')).'

'; $html.= ' '; foreach ($friends AS $key => $friend) { $orders = Order::getCustomerOrders($friend['id_customer']); $html.= ' '; } $html.= '
'.$this->l('ID').' '.$this->l('Name').' '.$this->l('Email').' '.$this->l('Registration date').' '.$this->l('Sponsored customers').' '.$this->l('Placed orders').' '.$this->l('Inscribed').'
'.(intval($friend['id_customer']) ? $friend['id_customer'] : '--').' '.$friend['firstname'].' '.$friend['lastname'].' '.$friend['email'].' '.Tools::displayDate($friend['date_add'], intval($cookie->id_lang), true).' '.sizeof(ReferralProgramModule::getSponsorFriend($friend['id_customer'])).' '.($orders ? sizeof($orders) : 0).' '.(intval($friend['id_customer']) ? '' : '').'
'; } else $html.= $customer->firstname.' '.$customer->lastname.' '.$this->l('has not sponsored any friends yet.'); return $html.'

'; } /** * Hook called when a order is confimed * display a message to customer about sponsor discount */ public function hookOrderConfirmation($params) { $order = $params['objOrder']; if ($order AND !Validate::isLoadedObject($order)) return die (Tools::displayError('Incorrect object Order.')); $customer = new Customer($order->id_customer); $stats = $customer->getStats(); $nbOrdersCustomer = intval($stats['nb_orders']) + 1; // hack to count current order $referralprogram = new ReferralProgramModule(ReferralProgramModule::isSponsorised(intval($customer->id), true)); if (!Validate::isLoadedObject($referralprogram)) return false; $sponsor = new Customer($referralprogram->id_sponsor); if (intval($nbOrdersCustomer) == intval($this->_configuration['REFERRAL_ORDER_QUANTITY'])) { $discount = new Discount($referralprogram->id_discount_sponsor); if (!Validate::isLoadedObject($discount)) return false; $discount_display = $discount->display($discount->value, $discount->id_discount_type, new Currency($order->id_currency)); global $smarty; $smarty->assign(array( 'discount' => $discount_display, 'sponsor_firstname' => $sponsor->firstname, 'sponsor_lastname' => $sponsor->lastname )); return $this->display(__FILE__, 'order-confirmation.tpl'); } return false; } /** * Hook called when order status changed * register a discount for sponsor and send him an e-mail */ public function hookUpdateOrderStatus($params) { if (!Validate::isLoadedObject($params['newOrderStatus'])) die (Tools::displayError('Some parameters are missing.')); $orderState = $params['newOrderStatus']; $order = new Order(intval($params['id_order'])); if ($order AND !Validate::isLoadedObject($order)) die (Tools::displayError('Incorrect object Order.')); $customer = new Customer($order->id_customer); $stats = $customer->getStats(); $nbOrdersCustomer = intval($stats['nb_orders']) + 1; // hack to count current order $referralprogram = new ReferralProgramModule(ReferralProgramModule::isSponsorised(intval($customer->id), true)); if (!Validate::isLoadedObject($referralprogram)) return false; $sponsor = new Customer($referralprogram->id_sponsor); if (intval($orderState->logable) AND $nbOrdersCustomer >= intval($this->_configuration['REFERRAL_ORDER_QUANTITY']) AND $referralprogram->registerDiscountForSponsor(intval($order->id_currency))) { $discount = new Discount($referralprogram->id_discount_sponsor); $currency = new Currency($order->id_currency); $discount_display = $discount->display($discount->value, $discount->id_discount_type, $currency); $data = array( '{sponsored_firstname}' => $customer->firstname, '{sponsored_lastname}' => $customer->lastname, '{discount_display}' => $discount_display, '{discount_name}' => $discount->name ); Mail::Send(intval($order->id_lang), 'referralprogram-congratulations', $this->l('Congratulations!'), $data, $sponsor->email, $sponsor->firstname.' '.$sponsor->lastname, strval(Configuration::get('PS_SHOP_EMAIL')), strval(Configuration::get('PS_SHOP_NAME')), NULL, NULL, dirname(__FILE__).'/mails/'); return true; } return false; } } ?>