✏️ 正在编辑: atos.php
路径:
/home/bpioifn/www/pigmentse/modules/atos/atos.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php /** * 2007-2014 PrestaShop * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to http://www.prestashop.com for more information. * * @author PrestaShop SA <contact@prestashop.com> * @copyright 2007-2014 PrestaShop SA * @license http://addons.prestashop.com/en/content/12-terms-and-conditions-of-use * International Registered Trademark & Property of PrestaShop SA */ use PrestaShop\PrestaShop\Core\Payment\PaymentOption; if (!defined('_PS_VERSION_')) { exit; } class Atos extends PaymentModule { public $bin_dir; public $ps_url; protected $js_path = null; protected $css_path = null; protected static $lang_cache; private $html; private $bank_array = [ 'elysnet' => 'HSBC / CCF', 'mercanet' => 'BNP Paribas', 'sogenactif' => 'Société Générale', 'etransactions' => 'Crédit Agricole', 'webaffaires' => 'Crédit du Nord / Kolb', 'sherlocks' => 'Crédit Lyonnais', 'cyberplus' => 'Banque Populaire / SMC', 'scellius' => 'Banque Postale', 'scelliusnet' => 'Banque Postale', 'citelis' => 'Crédit Mutuel' ]; private $bank_logo = [ 'default' => 'Atos_Worldline.png', 'elysnet' => 'HSBC.png', 'mercanet' => 'BNP_Paribas.jpg', 'sogenactif' => 'Societe_Generale.jpg', 'etransactions' => 'E-transactions.jpg', 'webaffaires' => 'Credit_Nord.jpg', 'sherlocks' => 'Credit_Lyonnais.png', 'cyberplus' => 'Banque_Populaire.png', 'scellius' => 'Banque_Postale.png', 'scelliusnet' => 'Banque_Postale.png', 'citelis' => 'CMB.jpg' ]; private $bank_paylib = [ 'mercanet', 'sogenactif', 'scellius', 'scelliusnet', ]; public function __construct() { $this->name = 'atos'; $this->version = '5.0.3'; $this->tab = 'payments_gateways'; $this->page = basename(__FILE__, '.php'); $this->bootstrap = true; $this->is_eu_compatible = 1; $this->author = 'PrestaShop'; $this->module_key = 'f6d0744cc640221a199f05fca47476e0'; $this->author_address = '0x64aa3c1e4034d07015f639b0e171b0d7b27d01aa'; $this->currencies = true; $this->currencies_mode = 'checkbox'; $this->bin_dir = dirname(__FILE__).'/bin/'; parent::__construct(); $this->ps_url = $this->setPSUrl(); $this->js_path = $this->_path.'views/js/'; $this->css_path = $this->_path.'views/css/'; $this->displayName = $this->l('Atos'); $this->description = $this->l('This payment module for banks using ATOS allows your customers to pay by Credit Card'); if (!count(Currency::checkPaymentCurrencies($this->id))) { $this->warning = $this->l('No currency has been set for this module.'); } } public function install() { $prems = substr(sprintf('%o', fileperms(dirname(__FILE__))), -4); $hooks = [ 'displayPaymentByBinaries', 'paymentOptions', 'displayReassurance' ]; if (parent::install() === false || $this->registerHook($hooks) === false) { return false; } if (!Configuration::get('ATOS_CAPTURE_MODE')) { Configuration::updateValue('ATOS_CAPTURE_MODE', 1); } if (!Configuration::get('ATOS_CAPTURE_DAY')) { Configuration::updateValue('ATOS_CAPTURE_DAY', 0); } if (!Configuration::get('ATOS_NOTIFICATION_EMAIL')) { Configuration::updateValue('ATOS_NOTIFICATION_EMAIL', Configuration::get('PS_SHOP_EMAIL')); } if (!Configuration::get('ATOS_ALLOW_CUSTOM')) { Configuration::updateValue('ATOS_ALLOW_CUSTOM', 0); } if (!Configuration::get('ATOS_DISABLE_3D')) { Configuration::updateValue('ATOS_DISABLE_3D', 1); } if ($prems != '0777') { chmod(dirname(__FILE__), octdec(0777)); } return true; } public function hookOrderConfirmation($params) { if ($params['order']->module != $this->name) { return; } $this->context->smarty->assign('contact_url', $this->context->link->getPageLink('contact', true)); if ($params['order']->valid || $params['order']->current_state == _PS_OS_PAYMENT_) { $this->context->smarty->assign([ 'shop_name' => $this->context->shop->name, 'status' => 'ok', ]); } else { $this->context->smarty->assign('status', 'failed'); } return $this->context->smarty->fetch('module:atos/views/templates/hook/hookorderconfirmation.tpl'); } public function postProcess() { // Step 1 if (Tools::isSubmit('submitAtosID')) { Configuration::updateValue('ATOS_MERCHANT_ID', trim(Tools::getValue('ATOS_MERCHANT_ID'))); return 1; } // Step 2 if (Tools::isSubmit('submitAtosCertif') && isset($_FILES['ATOS_CERTIF']) && !$_FILES['ATOS_CERTIF']['error']) { if (!Configuration::get('ATOS_MERCHANT_ID')) { $this->html .= $this->displayError($this->l('Please to fill the MERCHANT ID before uploading certificate')); } else { if (move_uploaded_file($_FILES['ATOS_CERTIF']['tmp_name'], dirname(__FILE__).'/certif.fr.'.Configuration::get('ATOS_MERCHANT_ID'))) { $this->html .= $this->displayConfirmation($this->l('Certificate updated')); $atoscode = $this->findCertificatSetup(dirname(__FILE__).'/certif.fr.'.Configuration::get('ATOS_MERCHANT_ID')); if($atoscode) { $this->updateBank($atoscode); } } else { $this->html .= $this->displayError($this->l('Error in copying the certificat')); } } return 2; } // Step 3 if (Tools::isSubmit('submitAtosBank')) { $atoscode = ''; foreach ($this->bank_array as $key => &$value) { if ($key === pSQL(Tools::getValue('atos_bank'.$key))) { $atoscode = $key; break; } } unset($key, $value); $id_merchant = Configuration::get('ATOS_MERCHANT_ID'); if (!empty($atoscode) && !empty($id_merchant)) { $this->updateBank($atoscode); } else { $this->html .= $this->displayError($this->l('Please to fill the MERCHANT ID before selecting your bank')); } return 3; } // Step 4 Optional if (Tools::isSubmit('submitAtosOptions')) { $amex = (int)Tools::getValue('ATOS_ALLOW_AMEX'); $paylib = (int)Tools::getValue('ATOS_ALLOW_PAYLIB'); $custom = (int)Tools::getValue('ATOS_ALLOW_CUSTOM'); $capture_mode = (int)Tools::getValue('ATOS_CAPTURE_MODE'); $capture_day = (int)Tools::getValue('ATOS_CAPTURE_DAY'); $treeDSecure = (int)Tools::getValue('ATOS_DISABLE_3D'); $treeDSecureMinimum = (float)Tools::getValue('ATOS_DISABLE_3D_MINIMUM'); $email = Tools::getValue('ATOS_NOTIFICATION_EMAIL'); if (empty($email) || Validate::isEmail($email)) { Configuration::updateValue('ATOS_NOTIFICATION_EMAIL', $email); } else { $this->html .= $this->displayError($this->l('please specify a valid e-mail address or nothing at all')); } Configuration::updateValue('ATOS_ALLOW_AMEX', $amex); Configuration::updateValue('ATOS_ALLOW_PAYLIB', $paylib); Configuration::updateValue('ATOS_ALLOW_CUSTOM', $custom); Configuration::updateValue('ATOS_DISABLE_3D', $treeDSecure); Configuration::updateValue('ATOS_CAPTURE_DAY', $capture_day); Configuration::updateValue('ATOS_CAPTURE_MODE', $capture_mode); Configuration::updateValue('ATOS_DISABLE_3D_MINIMUM', $treeDSecureMinimum); Configuration::updateValue('ATOS_REDIRECT', (int)Tools::getValue('ATOS_REDIRECT')); Configuration::updateValue('ATOS_ERROR_BEHAVIOR', (int)Tools::getValue('ATOS_ERROR_BEHAVIOR')); $this->html .= $this->displayConfirmation($this->l('Settings updated')); // Restore default parmcom $this->restoreParmcom(); // Edit the parmcom $this->editParmcom(); return 4; } } /** * Find the bank setup by using the certificat */ public function findCertificatSetup($file_name) { $regex = '#[a-zA-Z_]+[,][0-9\/]+[,][a-zA-Z0-9]+[,][a-zA-Z0-9]+[,][a-zA-Z0-9]+#'; $content = Tools::file_get_contents($file_name); $list = array(); if (!$content) { return false; } if (!preg_match_all($regex, $content, $matches) || !$matches[0][0]) { return false; } $list = explode(',', strtolower($matches[0][0])); if (!array_key_exists($list[3], $this->bank_array)) { return false; } return $list[3]; } /** * Update Bank setup */ public function updateBank($atoscode) { $pathfile_content = ''; // Restore default parmcom $this->restoreParmcom(); Configuration::updateValue('ATOS_BANK', trim($atoscode)); $pathfile_content = 'DEBUG!NO!'."\n".'D_LOGO!'.__PS_BASE_URI__.'modules/atos/views/img/logos/!'."\n". 'F_CERTIFICATE!'.dirname(__FILE__).'/certif!'."\n".'F_PARAM!'.dirname(__FILE__).'/parmcom!'."\n". 'F_DEFAULT!'.dirname(__FILE__).'/parmcom.'.$atoscode.'!'; if (!file_put_contents(dirname(__FILE__).'/pathfile', $pathfile_content)) { $this->html .= $this->displayError($this->l('Impossible to create pathfile')); } if (!file_put_contents(dirname(__FILE__).'/parmcom.'.Configuration::get('ATOS_MERCHANT_ID'), "\nADVERT!logo.jpg!\n")) { $this->html .= $this->displayError($this->l('Impossible to create parmcom')); } $this->html .= $this->displayConfirmation($this->l('Your bank have been selected')); $this->editParmcom(); } public function editParmcom() { $amex = (int)Configuration::get('ATOS_ALLOW_AMEX'); $paylib = (int)Configuration::get('ATOS_ALLOW_PAYLIB'); $bank = Configuration::get('ATOS_BANK'); $parcomedit = dirname(__FILE__).'/parmcom.'.$bank; $string = 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2!'; $data = ''; if ($amex === 1 && $paylib === 1 && in_array($bank, $this->bank_paylib)) { $data = Tools::file_get_contents($parcomedit); $data = str_replace($string, 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,AMEX,2,PAYLIB,2!', $data); file_put_contents($parcomedit, $data); } elseif ($paylib === 1 && in_array($bank, $this->bank_paylib)) { $data = Tools::file_get_contents($parcomedit); $data = str_replace($string, 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,PAYLIB,2!', $data); file_put_contents($parcomedit, $data); } elseif ($amex === 1 || (!in_array($bank, $this->bank_paylib) && $amex !== 0)) { $data = Tools::file_get_contents($parcomedit); $data = str_replace($string, 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,AMEX,2!', $data); file_put_contents($parcomedit, $data); } unset($this->bank_paylib); } public function restoreParmcom() { $bank = Configuration::get('ATOS_BANK'); $parcomedit = dirname(__FILE__).'/parmcom.'.$bank; $string = 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2!'; $data = Tools::file_get_contents($parcomedit); $old = 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,AMEX,2,PAYLIB,2!'; $data = str_replace($old, $string, $data); $old = 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,AMEX,2!'; $data = str_replace($old, $string, $data); $old = 'PAYMENT_MEANS!CB,2,VISA,2,MASTERCARD,2,PAYLIB,2!'; $data = str_replace($old, $string, $data); file_put_contents($parcomedit, $data); } public function getProperBin() { $file_list = Tools::scandir($this->bin_dir, ''); $ignore_list = ['.', '..', 'index.php', 'request.exe', 'response.exe']; $handle = array_diff($file_list, $ignore_list); foreach ($handle as $file) { $is_response = stristr($file, 'response'); if($is_response !== false) { $result = $this->simpleExec($this->bin_dir.$file); if (!empty($result)) { if ($file == 'response') { break; } $suffix = str_replace('response', '', $file); $this->renameBin($suffix); } unset($result); } } unset($handle, $file, $ignore_list, $file_list); } public function renameBin($suffix) { if (file_exists($this->bin_dir.'request'.$suffix)) { rename($this->bin_dir.'request', $this->bin_dir.'request_old'); rename($this->bin_dir.'request'.$suffix, $this->bin_dir.'request'); } if (file_exists($this->bin_dir.'response'.$suffix)) { rename($this->bin_dir.'response', $this->bin_dir.'response_old'); rename($this->bin_dir.'response'.$suffix, $this->bin_dir.'response'); } } public function simpleExec($cmd) { exec($cmd, $output); return $output; } public function getContent() { // Submit process $is_submit = $this->postProcess(); // Fetch configuration $exec = is_callable('exec'); $safe_mode = ini_get('safe_mode'); $bank = Configuration::get('ATOS_BANK'); $amex = (int)Configuration::get('ATOS_ALLOW_AMEX'); $capture_mode = (int)Configuration::get('ATOS_CAPTURE_MODE'); $capture_day = (int)Configuration::get('ATOS_CAPTURE_DAY'); $treeDSecure = (int)Configuration::get('ATOS_DISABLE_3D'); $treeDSecureMinimum = (float)Configuration::get('ATOS_DISABLE_3D_MINIMUM'); $paylib = (int)Configuration::get('ATOS_ALLOW_PAYLIB'); $custom = (int)Configuration::get('ATOS_ALLOW_CUSTOM'); $redirect = (int)Configuration::get('ATOS_REDIRECT'); $id_merchant = Configuration::get('ATOS_MERCHANT_ID'); $shop_enable = (int)Configuration::get('PS_SHOP_ENABLE'); $behavior = (int)Configuration::get('ATOS_ERROR_BEHAVIOR'); $is_win = (Tools::strtoupper(Tools::substr(PHP_OS, 0, 3)) === 'WIN'); $notification = Configuration::get('ATOS_NOTIFICATION_EMAIL'); $response = is_executable($this->bin_dir.'response'.(((int)$is_win === 1) ? '.exe' : '')); $requests = is_executable($this->bin_dir.'request'.(((int)$is_win === 1) ? '.exe' : '')); // Binary auto configuration if ($exec && (int)$is_win === 0) { $result = $this->simpleExec($this->bin_dir.'response'); if (empty($result)) { $this->getProperBin(); } unset($result); } // We load asset $this->loadAsset(); /* Language for documentation in back-office */ $iso_code = Context::getContext()->language->iso_code; switch ($iso_code) { case 'en': $lang = 'EN'; break; case 'fr': default: $lang = 'FR'; break; } $this->context->smarty->assign([ 'exec' => $exec, 'bank' => $bank, 'amex' => $amex, 'is_win' => $is_win, 'paylib' => $paylib, 'custom' => $custom, 'request' => $requests, 'behavior' => $behavior, 'response' => $response, 'redirect' => $redirect, 'is_submit' => $is_submit, 'safe_mode' => $safe_mode, 'bin_dir' => $this->bin_dir, 'shop_enable' => $shop_enable, 'id_merchant' => $id_merchant, 'capture_day' => $capture_day, 'treeDSecure' => $treeDSecure, 'capture_mode' => $capture_mode, 'notification' => $notification, 'bank_list' => $this->bank_array, 'form_uri' => $_SERVER['REQUEST_URI'], 'treeDSecureMinimum' => $treeDSecureMinimum, 'currency_sign' => $this->context->currency->sign, 'pathfile' => (int)file_exists(dirname(__FILE__).'/pathfile'), 'certificat' => (int)file_exists(dirname(__FILE__).'/certif.fr.'.$id_merchant), 'parmcom' => (int)file_exists(dirname(__FILE__).'/parmcom.'.$id_merchant), 'html' => $this->html, 'module_name' => $this->name, 'module_version' => $this->version, 'debug_mode' => (int)_PS_MODE_DEV_, 'lang_select' => self::$lang_cache, 'module_display' => $this->displayName, 'multishop' => (int)Shop::isFeatureActive(), 'guide_link3' => 'docs/ATOS_WORLDLINE_'.$lang.'.pdf', 'guide_link1' => 'docs/atos_guide_integration_FR.pdf', 'guide_link2' => 'docs/atos_guide_personnalisation_FR.pdf', 'ps_version' => (bool)version_compare(_PS_VERSION_, '1.6', '>'), ]); unset($this->bank_array); return $this->display(__FILE__, 'views/templates/admin/configuration.tpl'); } private function setPSUrl() { if (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED_EVERYWHERE')) { $this->ps_url = Tools::getShopDomainSsl(true); } else { $this->ps_url = Tools::getShopDomain(true); } return $this->ps_url; } private function getURLReturnPage($customer, $cart) { $params = [ 'id_cart' => $cart->id, 'id_module' => $this->id, 'secure_key' => $customer->secure_key, ]; return $this->context->link->getModuleLink('atos', 'orderconfirmation', $params, true); } private function getData3D($cart) { $treeDSecure = (int)Configuration::get('ATOS_DISABLE_3D'); $treeDSecureMinimum = (float)Configuration::get('ATOS_DISABLE_3D_MINIMUM') * 100; if ( (int)$treeDSecure == 1 && ($treeDSecureMinimum == 0 || $treeDSecureMinimum <= ($cart->getOrderTotal() * 100)) ) { return '3D_BYPASS\;'; } } private function getData($cart, $return_page, $nx = null) { $data = $this->getData3D($cart); if ((int)Configuration::get('ATOS_REDIRECT')) { $data .= 'NO_RESPONSE_PAGE_POST=' . $return_page . '\;'; } return $data; } private function getCompatibilityCurrency($currency) { $array_currency_iso_num = array(); $currency_num = 0; // for 1.3 compatibility if (!isset($currency->iso_code_num) || $currency->iso_code_num === '') { $array_currency_iso_num = [ 'DKK' => 208, 'EUR' => 978, 'USD' => 840, 'GBP' => 826, 'SEK' => 752, 'AUD' => 036, 'CAD' => 124, 'ISK' => 352, 'JPY' => 392, 'NZD' => 554, 'NOK' => 578, 'CHF' => 756, 'TRY' => 949, ]; $currency_num = $array_currency_iso_num[$currency->iso_code]; } else { $currency_num = $currency->iso_code_num; } return $currency_num; } private function setSilentURL() { return Tools::getShopDomainSsl(true); } private function getAtosForm($cart, $nx = null) { $lang = new Language((int)$cart->id_lang); $customer = new Customer((int)$cart->id_customer); $currency = new Currency((int)$cart->id_currency); $ps_url = $this->ps_url . __PS_BASE_URI__; $ps_silent_url = $this->setSilentURL() . __PS_BASE_URI__; $ipn_page = $ps_silent_url.'modules/'.$this->name.'/validation.php'; $return_url = $this->getURLReturnPage($customer, $cart); $cancel_url = $ps_url.'modules/'.$this->name.'/atos_return.php'; $capture_day = (int)Configuration::get('ATOS_CAPTURE_DAY'); $capture_mode = (int)Configuration::get('ATOS_CAPTURE_MODE') ? 'AUTHOR_CAPTURE' : 'VALIDATION'; $is_win = (Tools::strtoupper(Tools::substr(PHP_OS, 0, 3)) === 'WIN'); // $custom = (int)Configuration::get('ATOS_ALLOW_CUSTOM'); // $custom_tpl = ''; // if ($custom === 1) { // $custom_tpl = ' templatefile=custom_tpl'; // } $parm = 'merchant_id='.Configuration::get('ATOS_MERCHANT_ID'). ' language='.$lang->iso_code. ' customer_id='.(int)$cart->id_customer. ' caddie='.(int)$cart->id. ' merchant_country=fr'. ' amount='.(int)round(sprintf('%f', $cart->getOrderTotal() * 100)). ' currency_code='.$this->getCompatibilityCurrency($currency). ' capture_day='.$capture_day. ' capture_mode='.$capture_mode. ' pathfile="'.dirname(__FILE__).'/pathfile"'. ' normal_return_url="'.$return_url.'"'. ' cancel_return_url="'.$cancel_url.'"'. ' automatic_response_url="'.$ipn_page.'"'. ' customer_ip_address='.Tools::substr(Tools::getRemoteAddr(), 0, 16). ' data="' . $this->getData($cart, $return_url, $nx) . '"'; if (!$result = exec($this->bin_dir.'request'.(((int)$is_win === 1) ? '.exe' : '').' '.$parm)) { return $this->l('Atos error: can\'t execute binary'); } unset($cart, $lang, $customer, $currency); $result_array = explode('!', $result); if ($result_array[1] == -1) { return $this->l('Atos error:').' '.$result_array[2]; } elseif (!isset($result_array[3])) { return $this->l('Atos error: can\'t execute request'); } return $result_array[3]; } public function getAtosPaymentOption() { $option = new PaymentOption(); $option->setCallToActionText($this->l('Pay by card with Atos')); $option->setModuleName('atos'); $option->setBinary(true); return $option; } public function hookPaymentOptions($params) { $paymentOptions = []; if (!$this->active) { return; } if (!$this->checkCurrency($params['cart'])) { return; } $paymentOptions = [ $this->getAtosPaymentOption(), ]; return $paymentOptions; } public function hookDisplayPaymentByBinaries($params) { if (!$this->active) { return; } if (!$this->checkCurrency($params['cart'])) { return; } $this->context->controller->addCSS($this->css_path.'front_atos.css', 'all'); if ($params['cart']->getOrderTotal() < 1.00) { return $this->context->smarty->fetch('module:atos/views/templates/hook/payment.tpl'); } if (Configuration::get('ATOS_BANK') == false) { $logo = $this->bank_logo["default"]; } else { $logo = $this->bank_logo[Configuration::get('ATOS_BANK')]; } $this->context->smarty->assign([ 'this_path' => $this->_path, 'atos' => $this->getAtosForm($params['cart']), 'logo_class' => Configuration::get('ATOS_BANK'), 'logo' => $logo, 'minimumAmount' => Tools::displayPrice(1, $this->context->currency), ]); return $this->context->smarty->fetch('module:atos/views/templates/hook/payment.tpl'); } // TODO: Integrate a beautiful block. For now it's just the bank logo. public function hookDisplayReassurance($params) { if (!$this->active) { return; } if (!$this->checkCurrency($params['cart'])) { return; } if (Configuration::get('ATOS_BANK') == false) { $logo = $this->bank_logo["default"]; } else { $logo = $this->bank_logo[Configuration::get('ATOS_BANK')]; } $this->context->smarty->assign([ 'bank' => Configuration::get('ATOS_BANK'), 'this_path' => $this->_path, 'logo' => $logo, 'logo_class' => Configuration::get('ATOS_BANK'), ]); return $this->context->smarty->fetch('module:atos/views/templates/hook/reassurance.tpl'); } // @see https://github.com/PrestaShop/paymentexample/blob/master/paymentexample.php public function checkCurrency($cart) { $currency_order = new Currency($cart->id_currency); $currencies_module = $this->getCurrency($cart->id_currency); if (is_array($currencies_module)) { foreach ($currencies_module as $currency_module) { if ($currency_order->id == $currency_module['id_currency']) { return true; } } } return false; } // @see $this->__construct() private function getLang() { if (self::$lang_cache == null && !is_array(self::$lang_cache)) { self::$lang_cache = array(); if ($languages = Language::getLanguages()) { foreach ($languages as &$row) { $exprow = explode(' (', $row['name']); $subtitle = (isset($exprow[1]) ? trim(Tools::substr($exprow[1], 0, -1)) : ''); self::$lang_cache[$row['iso_code']] = array ( 'title' => trim($exprow[0]), 'subtitle' => $subtitle ); } /* Clean memory */ unset($row, $exprow, $subtitle, $languages); } } } /** * Loads asset resources */ public function loadAsset() { $js = [ $this->js_path.'bootstrap-select.min.js', $this->js_path.$this->name.'.js' ]; $css = [ $this->css_path.'font-awesome.min.css', $this->css_path.'bootstrap-select.min.css', $this->css_path.'bootstrap-responsive.min.css', $this->css_path.$this->name.'.css', ]; $this->context->controller->addCSS($css, 'all'); $this->context->controller->addJS($js); // Clean memory unset($js, $css); } }
💾 保存文件
← 返回文件管理器