From ae5fc92bf764a1eecbd5bf63676aa3cf0ebbdcd2 Mon Sep 17 00:00:00 2001 From: rMalie Date: Mon, 3 Oct 2011 15:48:07 +0000 Subject: [PATCH] // Merge -> revision 8984 git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@8988 b9a71923-0436-4b27-9f14-aed3839534dd --- admin-dev/ajax-tab.php | 3 +- admin-dev/tabs/AdminImport.php | 21 +- admin-dev/tabs/AdminModules.php | 134 ++++++-- classes/Cache.php | 4 - classes/LocalizationPack.php | 2 + classes/PaymentModule.php | 52 +++ classes/Product.php | 6 +- classes/ProductDownload.php | 32 +- classes/Search.php | 5 - classes/Tools.php | 58 +++- classes/tax/Tax.php | 4 + .../webservice/WebserviceOutputBuilder.php | 153 ++++----- classes/webservice/WebserviceRequest.php | 295 +++++++++--------- docs/csv_import/.htaccess | 1 + docs/csv_import/adresses_import.csv | 4 + docs/csv_import/categories_import.csv | 4 + docs/csv_import/combinations_import.csv | 3 + docs/csv_import/customers_import.csv | 3 + docs/csv_import/manufacturer_import.csv | 3 + docs/csv_import/products_import.csv | 3 + docs/csv_import/suppliers_import.csv | 3 + install-dev/index.php | 2 +- install-dev/sql/db_settings_lite.sql | 9 +- localization/ca.xml | 2 +- modules/autoupgrade/AdminSelfUpgrade.php | 39 +-- modules/autoupgrade/en.php | 4 + modules/blockcms/en.php | 4 + modules/blockcustomerprivacy/de.php | 4 + modules/blockcustomerprivacy/en.php | 4 + modules/blockcustomerprivacy/it.php | 4 + modules/blocklayered/blocklayered.js | 29 ++ modules/blocklayered/blocklayered.php | 26 +- modules/blocklayered/en.php | 4 + modules/canadapost/de.php | 4 + modules/canadapost/en.php | 4 + modules/canadapost/es.php | 4 + modules/canadapost/it.php | 4 + modules/ebay/config.xml | 1 - modules/ebay/ebay.php | 2 +- modules/importerosc/en.php | 4 + modules/livezilla/en.php | 4 + modules/moneybookers/en.php | 4 + modules/ogone/en.php | 4 + modules/paypal/en.php | 4 + modules/paysafecard/en.php | 4 + modules/prestafraud/en.php | 4 + modules/producttooltip/en.php | 4 + modules/reverso/en.php | 4 + modules/shopimporter/en.php | 4 + modules/shopimporter/shopimporter.php | 2 +- modules/socolissimo/en.php | 4 + modules/statscheckup/en.php | 4 + modules/statsforecast/en.php | 4 + modules/statsstock/en.php | 4 + modules/themeinstallator/en.php | 4 + modules/treepodia/en.php | 4 + modules/trustedshops/en.php | 4 + modules/twenga/en.php | 4 + modules/upscarrier/en.php | 4 + modules/uspscarrier/en.php | 4 + 60 files changed, 669 insertions(+), 356 deletions(-) create mode 100755 docs/csv_import/.htaccess create mode 100644 docs/csv_import/adresses_import.csv create mode 100644 docs/csv_import/categories_import.csv create mode 100644 docs/csv_import/combinations_import.csv create mode 100644 docs/csv_import/customers_import.csv create mode 100644 docs/csv_import/manufacturer_import.csv create mode 100644 docs/csv_import/products_import.csv create mode 100644 docs/csv_import/suppliers_import.csv create mode 100644 modules/autoupgrade/en.php create mode 100644 modules/blockcms/en.php create mode 100644 modules/blockcustomerprivacy/de.php create mode 100644 modules/blockcustomerprivacy/en.php create mode 100644 modules/blockcustomerprivacy/it.php create mode 100644 modules/blocklayered/en.php create mode 100644 modules/canadapost/de.php create mode 100644 modules/canadapost/en.php create mode 100644 modules/canadapost/es.php create mode 100644 modules/canadapost/it.php create mode 100644 modules/importerosc/en.php create mode 100644 modules/livezilla/en.php create mode 100644 modules/moneybookers/en.php create mode 100644 modules/ogone/en.php create mode 100644 modules/paypal/en.php create mode 100644 modules/paysafecard/en.php create mode 100644 modules/prestafraud/en.php create mode 100644 modules/producttooltip/en.php create mode 100644 modules/reverso/en.php create mode 100644 modules/shopimporter/en.php create mode 100644 modules/socolissimo/en.php create mode 100644 modules/statscheckup/en.php create mode 100644 modules/statsforecast/en.php create mode 100644 modules/statsstock/en.php create mode 100644 modules/themeinstallator/en.php create mode 100644 modules/treepodia/en.php create mode 100644 modules/trustedshops/en.php create mode 100644 modules/twenga/en.php create mode 100644 modules/upscarrier/en.php create mode 100644 modules/uspscarrier/en.php diff --git a/admin-dev/ajax-tab.php b/admin-dev/ajax-tab.php index 6aa122b9c..bb03c332a 100755 --- a/admin-dev/ajax-tab.php +++ b/admin-dev/ajax-tab.php @@ -36,7 +36,6 @@ if (!isset($_POST['controller']) && isset($_POST['tab'])) $_POST['controller'] = strtolower($_POST['tab']); if (!isset($_REQUEST['controller']) && isset($_REQUEST['tab'])) $_REQUEST['controller'] = strtolower($_REQUEST['tab']); - + Dispatcher::getInstance()->setControllerDirectories(array(_PS_ADMIN_DIR_.'/tabs/', _PS_ADMIN_CONTROLLER_DIR_)); Dispatcher::getInstance()->dispatch(); - diff --git a/admin-dev/tabs/AdminImport.php b/admin-dev/tabs/AdminImport.php index 7ae252432..20a2eb636 100644 --- a/admin-dev/tabs/AdminImport.php +++ b/admin-dev/tabs/AdminImport.php @@ -1376,6 +1376,18 @@ class AdminImport extends AdminTab }; '; echo ' +
+ '.$this->l('Sample files').' + +
'.$this->l('Upload').'
@@ -1456,12 +1468,11 @@ class AdminImport extends AdminTab
-
- '.$this->l('Note that the category import does not support categories of the same name').'. +
+

'.$this->l('Note that the category import does not support categories of the same name').'.

+ +

'.$this->l('Note that references are not specified as UNIQUE in the database').'.

-
- '.$this->l('Note that references are not specified as UNIQUE in the database').'. -
'; } else diff --git a/admin-dev/tabs/AdminModules.php b/admin-dev/tabs/AdminModules.php index 6ac3a3f85..3d9238432 100644 --- a/admin-dev/tabs/AdminModules.php +++ b/admin-dev/tabs/AdminModules.php @@ -40,44 +40,83 @@ class AdminModules extends AdminTab private $listTabModules; private $listPartnerModules = array(); private $listNativeModules = array(); - private $_moduleCacheFile; + private $_moduleCacheFile = '/config/modules_list.xml'; + public static $xml_modules_list = 'http://www.prestashop.com/xml/modules_list.xml'; static private $MAX_DISP_AUTHOR = 20; // maximum length to display - function __construct() + public function __construct() { parent::__construct(); - $this->_moduleCacheFile = _PS_ROOT_DIR_.'/config/modules_list.xml'; + $this->listTabModules['administration'] = $this->l('Administration'); + $this->listTabModules['advertising_marketing'] = $this->l('Advertising & Marketing'); + $this->listTabModules['analytics_stats'] = $this->l('Analytics & Stats'); + $this->listTabModules['billing_invoicing'] = $this->l('Billing & Invoicing'); + $this->listTabModules['checkout'] = $this->l('Checkout'); + $this->listTabModules['content_management'] = $this->l('Content Management'); + $this->listTabModules['export'] = $this->l('Export'); + $this->listTabModules['front_office_features'] = $this->l('Front Office Features'); + $this->listTabModules['i18n_localization'] = $this->l('I18n & Localization'); + $this->listTabModules['merchandizing'] = $this->l('Merchandizing'); + $this->listTabModules['migration_tools'] = $this->l('Migration Tools'); + $this->listTabModules['payments_gateways'] = $this->l('Payments & Gateways'); + $this->listTabModules['payment_security'] = $this->l('Payment Security'); + $this->listTabModules['pricing_promotion'] = $this->l('Pricing & Promotion'); + $this->listTabModules['quick_bulk_update'] = $this->l('Quick / Bulk update'); + $this->listTabModules['search_filter'] = $this->l('Search & Filter'); + $this->listTabModules['seo'] = $this->l('SEO'); + $this->listTabModules['shipping_logistics'] = $this->l('Shipping & Logistics'); + $this->listTabModules['slideshows'] = $this->l('Slideshows'); + $this->listTabModules['smart_shopping'] = $this->l('Smart Shopping'); + $this->listTabModules['market_place'] = $this->l('Market Place'); + $this->listTabModules['social_networks'] = $this->l('Social Networks'); + $this->listTabModules['others'] = $this->l('Other Modules'); - // refresh modules_list.xml every week + if (file_exists(_PS_ROOT_DIR_.$this->_moduleCacheFile)) + $xmlModules = @simplexml_load_file(_PS_ROOT_DIR_.$this->_moduleCacheFile); + else + $xmlModules = false; + + if ($xmlModules) + { + foreach($xmlModules->children() as $xmlModule) + { + if ($xmlModule->attributes() == 'native') + foreach($xmlModule->children() as $module) + foreach($module->attributes() as $key => $value) + if ($key == 'name') + $this->listNativeModules[] = (string)$value; + + if ($xmlModule->attributes() == 'partner') + foreach ($xmlModule->children() as $module) + foreach ($module->attributes() as $key => $value) + if ($key == 'name') + $this->listPartnerModules[] = (string)$value; + } + } + } + + /** if modules_list.xml is outdated, + * this function will re-upload it from prestashop.com + * + * @return null + */ + public function ajaxProcessRefreshModuleList() + { + //refresh modules_list.xml every week if (!$this->isFresh()) + { $this->refresh(); + $this->status = 'refresh'; + } + else + $this->status = 'cache'; + } - $this->listTabModules = array( - 'administration' => $this->l('Administration'), 'advertising_marketing' => $this->l('Advertising & Marketing'), - 'analytics_stats' => $this->l('Analytics & Stats'), 'billing_invoicing' => $this->l('Billing & Invoicing'), 'checkout' => $this->l('Checkout'), - 'content_management' => $this->l('Content Management'), 'export' => $this->l('Export'), 'front_office_features' => $this->l('Front Office Features'), - 'i18n_localization' => $this->l('I18n & Localization'), 'merchandizing' => $this->l('Merchandizing'), 'migration_tools' => $this->l('Migration Tools'), - 'payments_gateways' => $this->l('Payments & Gateways'), 'payment_security' => $this->l('Payment Security'), 'pricing_promotion' => $this->l('Pricing & Promotion'), - 'quick_bulk_update' => $this->l('Quick / Bulk update'), 'search_filter' => $this->l('Search & Filter'), 'seo' => $this->l('SEO'), 'shipping_logistics' => $this->l('Shipping & Logistics'), - 'slideshows' => $this->l('Slideshows'), 'smart_shopping' => $this->l('Smart Shopping'), 'market_place' => $this->l('Market Place'), 'social_networks' => $this->l('Social Networks'), - 'others'=> $this->l('Other Modules') - ); - - $xmlModules = @simplexml_load_file($this->_moduleCacheFile); - - foreach($xmlModules->children() as $xmlModule) - if ($xmlModule->attributes() == 'native') - foreach($xmlModule->children() as $module) - foreach($module->attributes() as $key => $value) - if ($key == 'name') - $this->listNativeModules[] = (string)$value; - if ($xmlModule->attributes() == 'partner') - foreach($xmlModule->children() as $module) - foreach($module->attributes() as $key => $value) - if ($key == 'name') - $this->listPartnerModules[] = (string)$value; + public function displayAjaxRefreshModuleList() + { + echo Tools::jsonEncode(array('status' => $this->status)); } public function postProcess() @@ -343,7 +382,7 @@ class AdminModules extends AdminTab $return = ($method == 'install' ? 12 : 13); elseif ($echo === false) $module_errors[] = $name; - + if (Shop::isMultiShopActivated() && Context::shop() != Shop::CONTEXT_ALL && isset(Context::getContext()->tmpOldShop)) { Context::getContext()->shop = clone(Context::getContext()->tmpOldShop); @@ -443,10 +482,38 @@ class AdminModules extends AdminTab $(\'input[name="filtername"]\').result(function(event, data, formatted) { $(\'#filternameForm\').submit(); }); - }); + });'; + // the following to get modules_list.xml from prestashop.com + echo '$(document).ready(function(){ + try + { + resAjax = $.ajax({ + type:"POST", + url : "'. str_replace('index','ajax-tab',$currentIndex) . '", + async: true, + data : { + ajaxMode : "1", + ajax : "1", + token : "'.$this->token.'", + tab : "AdminModules", + action : "refreshModuleList" + }, + success : function(res,textStatus,jqXHR) + { + // res.status = cache or refresh + }, + error: function(res,textStatus,jqXHR) + { + alert("TECHNICAL ERROR"+res); + } + }); + } + catch(e){} + }); '; } + public static function sortModule($a, $b) { if (sizeof($a) == sizeof($b)) { @@ -666,7 +733,6 @@ class AdminModules extends AdminTab '.$this->l('Add a module from my computer').'  | '; - if (@fsockopen('www.prestashop.com', 80)) echo ' Add '.$this->l('Add a module from PrestaShop Addons').' @@ -968,15 +1034,15 @@ class AdminModules extends AdminTab public function isFresh($timeout = 604800000) { - if (file_exists($this->_moduleCacheFile)) - return ((time() - filemtime($this->_moduleCacheFile)) < $timeout); + if (file_exists(_PS_ROOT_DIR_ . $this->_moduleCacheFile)) + return ((time() - filemtime(_PS_ROOT_DIR_ . $this->_moduleCacheFile)) < $timeout); else return false; } public function refresh() { - return file_put_contents($this->_moduleCacheFile, Tools::file_get_contents('http://www.prestashop.com/xml/modules_list.xml')); + return file_put_contents(_PS_ROOT_DIR_.$this->_moduleCacheFile, Tools::file_get_contents($this->xml_modules_list)); } public function displaySelectedFilter() diff --git a/classes/Cache.php b/classes/Cache.php index 9313ee519..c1da488b7 100755 --- a/classes/Cache.php +++ b/classes/Cache.php @@ -62,10 +62,6 @@ abstract class CacheCore { } - protected function __destruct() - { - } - protected function isBlacklist($query) { foreach ($this->_blackList AS $find) diff --git a/classes/LocalizationPack.php b/classes/LocalizationPack.php index 7962142aa..cbc958a6c 100644 --- a/classes/LocalizationPack.php +++ b/classes/LocalizationPack.php @@ -271,6 +271,8 @@ class LocalizationPackCore $this->_errors[] = Tools::displayError('An error occurred while importing the currency: ').strval($attributes['name']); return false; } + + PaymentModule::addCurrencyPermissions($currency->id); } } diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php index 37b6bebca..a914c8fbc 100644 --- a/classes/PaymentModule.php +++ b/classes/PaymentModule.php @@ -538,5 +538,57 @@ abstract class PaymentModuleCore extends Module return false; return (new Currency($id_currency)); } + + /** + * Allows specified payment modules to be used by a specific currency + * + * @since 1.4.5 + * @param int $id_currency + * @param array $id_module_list + * @return boolean + */ + public static function addCurrencyPermissions($id_currency, array $id_module_list = array()) + { + $values = ''; + if (count($id_module_list) == 0) + { + // fetch all installed module ids + $modules = PaymentModuleCore::getInstalledPaymentModules(); + foreach ($modules as $module) + $id_module_list[] = $module['id_module']; +} + + foreach ($id_module_list as $id_module) + $values .= '('.(int)$id_module.','.(int)$id_currency.'),'; + + if (!empty($values)) + { + return Db::getInstance()->Execute(' + INSERT INTO `'._DB_PREFIX_.'module_currency` (`id_module`, `id_currency`) + VALUES '.rtrim($values, ',') + ); + } + + return true; + } + + /** + * List all installed and active payment modules + * @see Module::getPaymentModules() if you need a list of module related to the user context + * + * @since 1.4.5 + * @return array module informations + */ + public static function getInstalledPaymentModules() + { + return Db::getInstance()->executeS(' + SELECT DISTINCT m.`id_module`, h.`id_hook`, m.`name`, hm.`position` + FROM `'._DB_PREFIX_.'module` m + LEFT JOIN `'._DB_PREFIX_.'hook_module` hm ON hm.`id_module` = m.`id_module` + LEFT JOIN `'._DB_PREFIX_.'hook` h ON hm.`id_hook` = h.`id_hook` + WHERE h.`name` = \'payment\' + AND m.`active` = 1 + '); + } } diff --git a/classes/Product.php b/classes/Product.php index f7741884b..d576d3f22 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -2656,7 +2656,11 @@ class ProductCore extends ObjectModel public static function duplicateDownload($id_product_old, $id_product_new) { - $resource = Db::getInstance()->ExecuteS('SELECT `display_filename`, `filename`, `date_add`, `date_expiration`, `nb_days_accessible`, `nb_downloadable`, `active`, `is_shareable` FROM `'._DB_PREFIX_.'product_download` WHERE `id_product` = '.(int)($id_product_old)); + $sql = 'SELECT `display_filename`, `filename`, `date_add`, `date_expiration`, `nb_days_accessible`, `nb_downloadable`, `active`, `is_shareable` + FROM `'._DB_PREFIX_.'product_download` + WHERE `id_product` = '.(int)$id_product_old; + $resource = Db::getInstance()->Execute($sql); + if (!Db::getInstance()->NumRows()) return true; $query = 'INSERT INTO `'._DB_PREFIX_.'product_download` (`id_product`, `display_filename`, `filename`, `date_add`, `date_expiration`, `nb_days_accessible`, `nb_downloadable`, `active`, `is_shareable`) VALUES'; diff --git a/classes/ProductDownload.php b/classes/ProductDownload.php index 7ef24e8e5..4d799babc 100644 --- a/classes/ProductDownload.php +++ b/classes/ProductDownload.php @@ -29,7 +29,7 @@ class ProductDownloadCore extends ObjectModel { /** @var integer Product id which download belongs */ public $id_product; - + /** @var integer Attribute Product id which download belongs */ public $id_product_attribute; @@ -38,13 +38,13 @@ class ProductDownloadCore extends ObjectModel /** @var string PhysicallyFilename the name of the file on hard disk */ public $filename; - + /** @var string DateDeposit when the file is upload */ public $date_add; /** @var string DateExpiration deadline of the file */ public $date_expiration; - + /** @var string NbDaysAccessible how many days the customer can access to file */ public $nb_days_accessible; @@ -53,7 +53,7 @@ class ProductDownloadCore extends ObjectModel /** @var boolean Active if file is accessible or not */ public $active = 1; - + /** @var boolean is_shareable indicates whether the product can be shared */ public $is_shareable = 0; @@ -133,20 +133,20 @@ class ProductDownloadCore extends ObjectModel public function getFields() { $this->validateFields(); + $date_expiration = $this->date_expiration; + if (!$date_expiration) + $date_expiration = '0000-00-00 00:00:00'; - if (!$this->date_expiration) - $this->date_expiration = '0000-00-00 00:00:00'; - - $fields['id_product'] = (int)($this->id_product); + $fields['id_product'] = (int)$this->id_product; $fields['id_product_attribute'] = pSQL($this->id_product_attribute); $fields['display_filename'] = pSQL($this->display_filename); $fields['filename'] = pSQL($this->filename); $fields['date_add'] = pSQL($this->date_add); - $fields['date_expiration'] = pSQL($this->date_expiration); - $fields['nb_days_accessible'] = (int)($this->nb_days_accessible); - $fields['nb_downloadable'] = (int)($this->nb_downloadable); - $fields['active'] = (int)($this->active); - $fields['is_shareable'] = (int)($this->is_shareable); + $fields['date_expiration'] = pSQL($date_expiration); + $fields['nb_days_accessible'] = (int)$this->nb_days_accessible; + $fields['nb_downloadable'] = (int)$this->nb_downloadable; + $fields['active'] = (int)$this->active; + $fields['is_shareable'] = (int)$this->is_shareable; return $fields; } @@ -220,7 +220,7 @@ class ProductDownloadCore extends ObjectModel WHERE `id_product_attribute` = '.(int)$id_product_attribute.' AND `active` = 1'); return self::$_productIds[$id_product_attribute]; } - + /** * Return the display filename from a physical filename * @@ -237,7 +237,7 @@ class ProductDownloadCore extends ObjectModel FROM `'._DB_PREFIX_.'product_download` WHERE `id_product` = '.(int)$id_product.' AND `active` = 1'); } - + /** * Return the display filename from a physical filename * @@ -254,7 +254,7 @@ class ProductDownloadCore extends ObjectModel FROM `'._DB_PREFIX_.'product_download` WHERE `filename` = \''.pSQL($filename).'\''); } - + /** * Return the filename from an id_product * diff --git a/classes/Search.php b/classes/Search.php index 3fd9cabdc..a3630063a 100644 --- a/classes/Search.php +++ b/classes/Search.php @@ -466,11 +466,6 @@ class SearchCore // If we find words that need to be indexed, they're added to the word table in the database if (count($pArray)) { - $list = ''; - foreach ($pArray AS $word => $weight) - $list .= '\''.$word.'\','; - $list = rtrim($list, ','); - $queryArray = array(); $queryArray2 = array(); foreach ($pArray AS $word => $weight) diff --git a/classes/Tools.php b/classes/Tools.php index f507ed345..5dea715b6 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -1206,11 +1206,11 @@ class ToolsCore else return false; } - + /** * @deprecated as of 1.5 use Media::minifyHTML() */ - + public static function minifyHTML($html_content) { Tools::displayAsDeprecated(); @@ -1237,7 +1237,7 @@ class ToolsCore $b = hexdec(substr($hex, 4, 2)); return (($r * 299) + ($g * 587) + ($b * 114)) / 1000; } - + /** * @deprecated as of 1.5 use Media::minifyHTMLpregCallback() */ @@ -1246,7 +1246,7 @@ class ToolsCore Tools::displayAsDeprecated(); return Media::minifyHTMLpregCallback($preg_matches); } - + /** * @deprecated as of 1.5 use Media::packJSinHTML() */ @@ -1255,7 +1255,7 @@ class ToolsCore Tools::displayAsDeprecated(); return Media::packJSinHTML($html_content); } - + /** * @deprecated as of 1.5 use Media::packJSinHTMLpregCallback() */ @@ -1285,7 +1285,7 @@ class ToolsCore } return false; } - + /** * @deprecated as of 1.5 use Media::minifyCSS() */ @@ -1341,7 +1341,7 @@ class ToolsCore /** * @deprecated as of 1.5 use Media::cccCss() */ - public static function cccCss($css_files) + public static function cccCss($css_files) { Tools::displayAsDeprecated(); return Media::cccCss($css_files); @@ -1351,14 +1351,14 @@ class ToolsCore /** * @deprecated as of 1.5 use Media::cccJS() */ - public static function cccJS($js_files) + public static function cccJS($js_files) { Tools::displayAsDeprecated(); return Media::cccJS($css_files); } private static $_cache_nb_media_servers = null; - + public static function getMediaServer($filename) { if (self::$_cache_nb_media_servers === null) @@ -1912,6 +1912,46 @@ FileETag INode MTime Size $result = min($post_max_size, $upload_max_filesize); return $result; } + + /** + * apacheModExists return true if the apache module $name is loaded + * @TODO move this method in class Information (when it will exist) + * + * @param string $name module name + * @return boolean true if exists + * @since 1.4.5.0 + */ + public static function apacheModExists($name) + { + if (function_exists('apache_get_modules')) + { + static $apacheModuleList = null; + + if (!is_array($apacheModuleList)) + $apacheModuleList = apache_get_modules(); + + // we need strpos (example can be evasive20 + foreach ($apacheModuleList as $module) + { + if (strpos($module, $name)!==false) + return true; + } + } + else + { + // If apache_get_modules does not exists, + // one solution should be parsing httpd.conf, + // but we could simple parse phpinfo(INFO_MODULES) return string + ob_start(); + phpinfo(INFO_MODULES); + $phpinfo = ob_get_contents(); + ob_end_clean(); + if (strpos($phpinfo, $module) !== false) + return true; + } + + return false; + } } /** diff --git a/classes/tax/Tax.php b/classes/tax/Tax.php index 09e6fd860..ea0348fe3 100644 --- a/classes/tax/Tax.php +++ b/classes/tax/Tax.php @@ -52,6 +52,10 @@ class TaxCore extends ObjectModel protected static $_product_country_tax = array(); protected static $_product_tax_via_rules = array(); + protected $webserviceParameters = array( + 'objectsNodeName' => 'taxes', + ); + public function getFields() { $this->validateFields(); diff --git a/classes/webservice/WebserviceOutputBuilder.php b/classes/webservice/WebserviceOutputBuilder.php index 48bd7f877..f8dc9ef10 100755 --- a/classes/webservice/WebserviceOutputBuilder.php +++ b/classes/webservice/WebserviceOutputBuilder.php @@ -1,6 +1,6 @@ 0, @@ -55,22 +55,22 @@ class WebserviceOutputBuilderCore 'PSWS-Version' => 0, 'Content-Type' => 0, ); - - /** + + /** * @var string Status header sent at return */ protected $status; - + public function __construct($ws_url) { $this->status = $_SERVER['SERVER_PROTOCOL'].' 200 OK'; $this->wsUrl = $ws_url; } - + /** * Set the render object for set the output format. * Set the Content-type for the http header. - * + * * @param WebserviceOutputInterface $obj_render * @throw WebserviceException if the object render is not an instance of WebserviceOutputInterface * @return $this @@ -79,14 +79,14 @@ class WebserviceOutputBuilderCore { if (!$obj_render instanceof WebserviceOutputInterface) throw new WebserviceException('Obj_render param must be an WebserviceOutputInterface object type', array(83, 500)); - + $this->objectRender = $obj_render; $this->objectRender->setWsUrl($this->wsUrl); if ($this->objectRender->getContentType()) $this->setHeaderParams('Content-Type', $this->objectRender->getContentType()); return $this; } - + /** * getter * @return WebserviceOutputInterface @@ -94,12 +94,12 @@ class WebserviceOutputBuilderCore public function getObjectRender() { return $this->objectRender; - } - + } + /** * Need to have the resource list to get the class name for an entity, - * To build - * + * To build + * * @param array $resources * @return $this */ @@ -108,13 +108,13 @@ class WebserviceOutputBuilderCore $this->wsResource = $resources; return $this; } - + /** * This method return an array with each http header params for a content. * This check each required params. - * + * * If this method is overrided don't forget to check required specific params (for xml etc...) - * + * * @return array */ public function buildHeader() @@ -127,7 +127,7 @@ class WebserviceOutputBuilderCore } return $return; } - + /** * @param $key The normalized key expected for an http response * @param $value @@ -142,7 +142,7 @@ class WebserviceOutputBuilderCore $this->headerParams[$key] = $value; return $this; } - + /** * @param null|string $key if null get all header params otherwise the params specified by the key * @throw WebserviceException if the key is corrupted (use Validate::isCleanHtml method) @@ -152,10 +152,10 @@ class WebserviceOutputBuilderCore public function getHeaderParams($key = null) { $return = ''; - + if (!is_null($key)) { - if (!is_null($key) && Validate::isCleanHtml($key)) + if (!Validate::isCleanHtml($key)) throw new WebserviceException('the key you write is a corrupted text.', array(95, 500)); if (!array_key_exists($key, $this->headerParams)) throw new WebserviceException(sprintf('The key %s does\'nt exist', $key), array(96, 500)); @@ -163,13 +163,13 @@ class WebserviceOutputBuilderCore } else $return = $this->headerParams; - + return $return; } - + /** * Delete all Header parameters previously set. - * + * * @return $this */ public function resetHeaderParams() @@ -177,7 +177,7 @@ class WebserviceOutputBuilderCore $this->headerParams = array(); return $this; } - + /** * @return string the normalized status for http request */ @@ -233,10 +233,10 @@ class WebserviceOutputBuilderCore break; } } - + /** * Build errors output using an error array - * + * * @param array $errors * @return string output in the format specified by WebserviceOutputBuilder::objectRender */ @@ -264,7 +264,7 @@ class WebserviceOutputBuilderCore } return $str_output; } - + /** * Build the resource list in the output format specified by WebserviceOutputBuilder::objectRender * @param $key_permissions @@ -290,11 +290,11 @@ class WebserviceOutputBuilderCore 'head' => (in_array('HEAD', $key_permissions[$resourceName]) ? 'true' : 'false'), ); $output .= $this->objectRender->renderNodeHeader($resourceName, array(), $more_attr); - + $output .= $this->objectRender->renderNodeHeader('description', array(), $more_attr); $output .= $resource['description']; $output .= $this->objectRender->renderNodeFooter('description', array()); - + if (!isset($resource['specific_management']) || !$resource['specific_management']) { $more_attr_schema = array( @@ -322,8 +322,8 @@ class WebserviceOutputBuilderCore * - list of entities, * - tree diagram of entity details (full or minimum), * - schema (synopsis & blank), - * - * @param array $objects each object created by entity asked + * + * @param array $objects each object created by entity asked * @see WebserviceOutputBuilder::executeEntityGetAndHead * @param null|string $schema_to_display if null display the entities list or entity details. * @param string|array $fields_to_display the fields allow for the output @@ -336,22 +336,22 @@ class WebserviceOutputBuilderCore $this->fieldsToDisplay = $fields_to_display; $this->depth = $depth; $output = ''; - + if ($schema_to_display != null) { $this->schemaToDisplay = $schema_to_display; $this->objectRender->setSchemaToDisplay($this->schemaToDisplay); - - // If a shema is asked the view must be an details type + + // If a shema is asked the view must be an details type $type_of_view = self::VIEW_DETAILS; } - + $ws_params = $objects['empty']->getWebserviceParameters(); - + // If a list is asked, need to wrap with a plural node if ($type_of_view === self::VIEW_LIST) $output .= $this->setIndent($depth).$this->objectRender->renderNodeHeader($ws_params['objectsNodeName'], $ws_params); - + if (is_null($this->schemaToDisplay)) { foreach ($objects as $key => $object) @@ -369,11 +369,11 @@ class WebserviceOutputBuilderCore { $output .= $this->renderSchema($objects['empty'], $ws_params); } - + // If a list is asked, need to wrap with a plural node if ($type_of_view === self::VIEW_LIST) $output .= $this->setIndent($depth).$this->objectRender->renderNodeFooter($ws_params['objectsNodeName'], $ws_params); - + if ($override) $output = $this->objectRender->overrideContent($output); return $output; @@ -381,7 +381,7 @@ class WebserviceOutputBuilderCore /** * Create the tree diagram with no details - * + * * @param $object create by the entity * @param $depth the depth for the tree diagram * @return string @@ -397,7 +397,7 @@ class WebserviceOutputBuilderCore /** * Build a schema blank or synopsis - * + * * @param $object create by the entity * @param $ws_params webserviceParams from the entity * @return string @@ -420,7 +420,7 @@ class WebserviceOutputBuilderCore /** * Build the entity detail. - * + * * @param ObjectModel $object create by the entity * @param int $depth the depth for the tree diagram * @return string @@ -430,14 +430,14 @@ class WebserviceOutputBuilderCore $output = ''; $ws_params = $object->getWebserviceParameters(); $output .= $this->setIndent($depth).$this->objectRender->renderNodeHeader($ws_params['objectNodeName'], $ws_params); - + if ($object->id != 0) { // This to add virtual Fields for a particular entity. $virtual_fields = $this->addVirtualFields($ws_params['objectsNodeName'], $object); if (!empty($virtual_fields)) $ws_params['fields'] = array_merge($ws_params['fields'], $virtual_fields); - + foreach ($ws_params['fields'] as $field_name => $field) { if ($this->fieldsToDisplay === 'full' || array_key_exists($field_name, $this->fieldsToDisplay)) @@ -468,7 +468,7 @@ class WebserviceOutputBuilderCore /** * Build a field and use recursivity depend on the depth parameter. - * + * * @param ObjectModel $object create by the entity * @param array $ws_params webserviceParams from the entity * @param string $field_name @@ -480,7 +480,7 @@ class WebserviceOutputBuilderCore { $output = ''; $show_field = true; - + if (isset($ws_params['hidden_fields']) && in_array($field_name, $ws_params['hidden_fields'])) return; @@ -489,9 +489,10 @@ class WebserviceOutputBuilderCore $field['synopsis_details'] = $this->getSynopsisDetails($field); if ($field_name === 'id') $show_field = false; - elseif (isset($field['setter']) && !$field['setter']) - $show_field = false; } + else if ($this->schemaToDisplay === 'blank') + if (isset($field['setter']) && !$field['setter']) + $show_field = false; // don't set any value for a schema if (isset($field['synopsis_details']) || $this->schemaToDisplay === 'blank') @@ -504,10 +505,10 @@ class WebserviceOutputBuilderCore $field['value'] = $object->$field['getter'](); elseif (!isset($field['value'])) $field['value'] = $object->$field_name; - + // this apply specific function for a particular field on a choosen entity $field = $this->overrideSpecificField($ws_params['objectsNodeName'], $field_name, $field, $object, $ws_params); - + // don't display informations for a not existant id if (substr($field['sqlId'], 0, 3) == 'id_' && $field['value'] == 0) { @@ -519,8 +520,8 @@ class WebserviceOutputBuilderCore // set "id" for each node name which display the id of the entity if ($field_name === 'id') $field['sqlId'] = 'id'; - - + + // don't display the node id for a synopsis schema if ($show_field) $output .= $this->setIndent($depth-1).$this->objectRender->renderField($field); @@ -528,8 +529,8 @@ class WebserviceOutputBuilderCore } /** - * - * + * + * * @param $object * @param $depth * @param $associations @@ -545,17 +546,17 @@ class WebserviceOutputBuilderCore { $getter = $association['getter']; $objects_assoc = array(); - + $fields_assoc = array(); if (isset($association['fields'])) - $fields_assoc = $association['fields']; - + $fields_assoc = $association['fields']; + $parent_details = array( 'object_id' => $object->id, 'entity_name' => $ws_params['objectNodeName'], 'entities_name' => $ws_params['objectsNodeName'], ); - + if (method_exists($object, $getter) && is_null($this->schemaToDisplay)) { $association_resources = $object->$getter(); @@ -571,7 +572,7 @@ class WebserviceOutputBuilderCore { $objects_assoc[] = ''; } - + $class_name = null; if (isset($this->wsResource[$assoc_name]['class']) && class_exists($this->wsResource[$assoc_name]['class'], true)) $class_name = $this->wsResource[$assoc_name]['class']; @@ -614,7 +615,7 @@ class WebserviceOutputBuilderCore $output .= $this->objectRender->renderAssociationWrapperFooter(); return $output; } - + private function renderFlatAssociation($object, $depth, $assoc_name, $resource_name, $fields_assoc, $object_assoc, $parent_details) { $output = ''; @@ -627,7 +628,7 @@ class WebserviceOutputBuilderCore $more_attr['xlink_resource'] = $this->wsUrl.$assoc_name.'/'.$object_assoc['id']; } $output .= $this->setIndent($depth-1).$this->objectRender->renderNodeHeader($resource_name, array(), $more_attr); - + foreach ($fields_assoc as $field_name=>$field) { if (!is_array($this->fieldsToDisplay) || in_array($field_name, $this->fieldsToDisplay[$assoc_name])) @@ -644,17 +645,17 @@ class WebserviceOutputBuilderCore } $field['entities_name'] = $assoc_name; $field['entity_name'] = $resource_name; - + if (!is_null($this->schemaToDisplay)) $field['synopsis_details'] = $this->getSynopsisDetails($field); - + $output .= $this->setIndent($depth-1).$this->objectRender->renderField($field); } } $output .= $this->setIndent($depth-1).$this->objectRender->renderNodeFooter($resource_name, array()); return $output; } - + public function setIndent($depth) { $string = ''; @@ -663,7 +664,7 @@ class WebserviceOutputBuilderCore $string .= "\t"; return $string; } - + public function getSynopsisDetails($field) { $arr_details = ''; @@ -675,9 +676,9 @@ class WebserviceOutputBuilderCore $arr_details['format'] = $field['validateMethod']; return $arr_details; } - + /** - * + * * @param string|object $object * @param string $method * @return $this @@ -689,9 +690,9 @@ class WebserviceOutputBuilderCore } catch (WebserviceException $e) { throw $e; } - + $this->specificFields[$field_name] = array('entity'=>$entity_name, 'object' => $object, 'method' => $method, 'type' => gettype($object)); - return $this; + return $this; } private function validateObjectAndMethod($object, $method) { @@ -712,7 +713,7 @@ class WebserviceOutputBuilderCore $object = new $this->specificFields[$field_name]['object'](); elseif ($this->specificFields[$field_name]['type'] == 'object') $object= $this->specificFields[$field_name]['object']; - + $field = $object->{$this->specificFields[$field_name]['method']}($field, $entity_object, $ws_params); } return $field; @@ -724,7 +725,7 @@ class WebserviceOutputBuilderCore } catch (WebserviceException $e) { throw $e; } - + $this->virtualFields[$entity_name][] = array('parameters' => $parameters, 'object' => $object, 'method' => $method, 'type' => gettype($object)); } public function getVirtualFields() @@ -743,7 +744,7 @@ class WebserviceOutputBuilderCore $object = new $function_infos['object'](); elseif ($function_infos['type'] == 'object') $object= $function_infos['object']; - + $return_fields = $object->{$function_infos['method']}($entity_object, $function_infos['parameters']); foreach ($return_fields as $field_name => $value) { @@ -756,7 +757,7 @@ class WebserviceOutputBuilderCore } return $arr_return; } - + public function setFieldsToDisplay($fields) { $this->fieldsToDisplay = $fields; diff --git a/classes/webservice/WebserviceRequest.php b/classes/webservice/WebserviceRequest.php index 74446f8b1..6a901f5ae 100644 --- a/classes/webservice/WebserviceRequest.php +++ b/classes/webservice/WebserviceRequest.php @@ -1,6 +1,6 @@ _outputEnabled; } - + public function setOutputEnabled($bool) { if (Validate::isBool($bool)) - $this->_outputEnabled = $bool; + $this->_outputEnabled = $bool; return $this; } - + /** * Get WebserviceRequest object instance (Singleton) * @@ -206,7 +206,7 @@ class WebserviceRequestCore self::$_instance = new WebserviceRequest::$ws_current_classname(); return self::$_instance; } - + protected function getOutputObject($type) { switch ($type) @@ -218,7 +218,7 @@ class WebserviceRequestCore } return $obj_render; } - + public static function getResources() { $resources = array( @@ -262,16 +262,17 @@ class WebserviceRequestCore 'stock_movement_reasons' => array('description' => 'The stock movement reason', 'class' => 'StockMvtReason'), 'shops' => array('description' => 'Shops from multi-shop feature', 'class' => 'Shop'), 'shop_groups' => array('description' => 'Shop groups from multi-shop feature', 'class' => 'GroupShop'), + 'taxes' => array('description' => 'The tax rate', 'class' => 'Tax'), ); ksort($resources); return $resources; } - + // @todo Check how get parameters // @todo : set this method out /** * This method is used for calculate the price for products on the output details - * + * * @param $field * @param $entity_object * @param $ws_params @@ -286,11 +287,11 @@ class WebserviceRequestCore } return $field; } - + // @todo : set this method out /** * This method is used for calculate the price for products on a virtual fields - * + * * @param $entity_object * @param array $parameters * @return array @@ -318,12 +319,12 @@ class WebserviceRequestCore $decimals = (isset($value['decimals']) ? $value['decimals'] : Configuration::get('PS_PRICE_ROUND_MODE')); $id_product_attribute = (isset($value['product_attribute']) ? $value['product_attribute'] : null); $id_county = (isset($value['county']) ? $value['county'] : null); - + $only_reduc = (isset($value['only_reduction']) ? $value['only_reduction'] : false); $use_reduc = (isset($value['use_reduction']) ? $value['use_reduction'] : true); $use_ecotax = (isset($value['use_ecotax']) ? $value['use_ecotax'] : Configuration::get('PS_USE_ECOTAX')); $specific_price_output = null; - $return_value = Product::priceCalculation(null, $value['object_id'], $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, + $return_value = Product::priceCalculation(null, $value['object_id'], $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $use_ecotax, $specific_price_output, null); $arr_return[$name] = array('sqlId'=>strtolower($name), 'value'=>$return_value); } @@ -332,7 +333,7 @@ class WebserviceRequestCore // @todo : set this method out /** * This method is used for calculate the price for products on a virtual fields - * + * * @param $entity_object * @param array $parameters * @return array @@ -347,7 +348,7 @@ class WebserviceRequestCore $arr_return = $this->specificPriceCalculation($parameters); return $arr_return; } - + /** * Start Webservice request * Check webservice activation @@ -356,7 +357,7 @@ class WebserviceRequestCore * Check HTTP Method * Execute the action * Display the result - * + * * @param string $key * @param string $method * @param string $url @@ -370,7 +371,7 @@ class WebserviceRequestCore // Time logger $this->_startTime = microtime(true); $this->objects = array(); - + // Two global vars, for compatibility with the PS core... global $webservice_call, $display_errors; $webservice_call = true; @@ -379,13 +380,13 @@ class WebserviceRequestCore $this->wsUrl = Tools::getHttpHost(true).__PS_BASE_URI__; // set the output object which manage the content and header structure and informations $this->objOutput = new WebserviceOutputBuilder($this->wsUrl); - + // Error handler set_error_handler(array($this, 'webserviceErrorHandler')); ini_set('html_errors', 'off'); - + $this->_key = trim($key); - + $this->outputFormat = isset($params['output_format']) ? $params['output_format'] : $this->outputFormat; // Set the render object to build the output on the asked format (XML, JSON, CSV, ...) $this->objOutput->setObjectRender($this->getOutputObject($this->outputFormat)); @@ -400,8 +401,8 @@ class WebserviceRequestCore $this->urlFragments = $params; $this->_inputXml = $inputXml; $this->depth = isset($this->urlFragments['depth']) ? (int)$this->urlFragments['depth'] : $this->depth; - - + + try { // Method below set a particular fonction to use on the price field for products entity // @see WebserviceRequest::getPriceForProduct() method @@ -415,7 +416,7 @@ class WebserviceRequestCore } catch (Exception $e) { $this->setError(500, $e->getMessage(), $e->getCode()); } - + if (isset($this->urlFragments['language'])) $this->_available_languages = $this->filterLanguage(); else @@ -423,25 +424,25 @@ class WebserviceRequestCore foreach (Language::getLanguages() as $key=>$language) $this->_available_languages[] = $language['id_lang']; } - + if (empty($this->_available_languages)) $this->setError(400, 'language is not available', 81); - + // Need to set available languages for the render object. // Thus we can filter i18n field for the output // @see WebserviceOutputXML::renderField() method for example $this->objOutput->objectRender->setLanguages($this->_available_languages); - + // check method and resource if (empty($this->errors) && $this->checkResource() && $this->checkHTTPMethod()) { // The resource list is necessary for build the output $this->objOutput->setWsResources($this->resourceList); - + // if the resource is a core entity... if (!isset($this->resourceList[$this->urlSegment[0]]['specific_management']) || !$this->resourceList[$this->urlSegment[0]]['specific_management']) { - + // load resource configuration if ($this->urlSegment[0] != '') { @@ -472,7 +473,7 @@ class WebserviceRequestCore $this->executeEntityDelete(); break; } - // Need to set an object for the WebserviceOutputBuilder object in any case + // Need to set an object for the WebserviceOutputBuilder object in any case // because schema need to get webserviceParameters of this object if (isset($object)) $this->objects['empty'] = $object; @@ -489,7 +490,7 @@ class WebserviceRequestCore $this->objectSpecificManagement = new $specificObjectName(); $this->objectSpecificManagement->setObjectOutput($this->objOutput) ->setWsObject($this); - + try { $this->objectSpecificManagement->manage(); } catch (WebserviceException $e) { @@ -506,8 +507,8 @@ class WebserviceRequestCore unset($webservice_call); unset ($display_errors); } - - + + /** * Set a webservice error * @@ -522,7 +523,7 @@ class WebserviceRequestCore $this->objOutput->setStatus($status); $this->errors[] = $display_errors ? array($code, $label) : 'Internal error. To see this error please display the PHP errors.'; } - + /** * Set a webservice error and propose a new value near from the available values * @@ -537,7 +538,7 @@ class WebserviceRequestCore { $this->setError($num, $label.'. Did you mean: "'.$this->getClosest($value, $available_values).'"?'.(count($available_values) > 1 ? ' The full list is: "'.implode('", "', $available_values).'"' : ''), $code); } - + /** * Return the nearest value picked in the values list * @@ -565,9 +566,9 @@ class WebserviceRequestCore } return $closest; } - + /** - * Used to replace the default PHP error handler, in order to display PHP errors in a XML format + * Used to replace the default PHP error handler, in order to display PHP errors in a XML format * * @param string $errno contains the level of the error raised, as an integer * @param array $errstr contains the error message, as a string @@ -579,7 +580,7 @@ class WebserviceRequestCore { if (!(error_reporting() & $errno)) return; - + switch($errno) { case E_ERROR: @@ -626,7 +627,7 @@ class WebserviceRequestCore } return true; } - + /** * Check if there is one or more error * @@ -636,7 +637,7 @@ class WebserviceRequestCore { return (boolean)$this->errors; } - + /** * Check request authentication * @@ -675,7 +676,7 @@ class WebserviceRequestCore { $this->setError(401, 'Authentification key is not active', 20); } - + if (!$this->keyPermissions) { $this->setError(401, 'No permission for this authentication key', 21); @@ -696,7 +697,7 @@ class WebserviceRequestCore } } } - + /** * Check webservice activation * @@ -711,7 +712,7 @@ class WebserviceRequestCore } return true; } - + protected function shopHasRight($key) { $sql = 'SELECT 1 @@ -727,7 +728,7 @@ class WebserviceRequestCore } return true; } - + protected function shopExists($params) { // Case no shop specified @@ -736,7 +737,7 @@ class WebserviceRequestCore self::$shopIDs[] = Configuration::get('PS_SHOP_DEFAULT'); return true; } - + if ($params['id_shop'][0] == '[' && $params['id_shop'][strlen($params['id_shop']) - 1] == ']') $shops = explode(',', substr($params['id_shop'], 1, strlen($params['id_shop']) - 2)); else @@ -767,7 +768,7 @@ class WebserviceRequestCore $this->setError(404, 'This shop id doesn\'t exist', 129); return false; } - + /** * Check HTTP method * @@ -785,7 +786,7 @@ class WebserviceRequestCore return true; return false; } - + /** * Check resource validity * @@ -812,8 +813,8 @@ class WebserviceRequestCore } return true; } - - + + protected function setObjects() { $objects = array(); @@ -840,18 +841,18 @@ class WebserviceRequestCore $objects[] = $object; } } - + if (!empty($arr_avoid_id) || empty($ids)) { $this->setError(404, 'Id(s) not exists: '.implode(', ', $arr_avoid_id), 87); $this->_outputEnabled = true; } - else + else { - + } } - + protected function parseDisplayFields($str) { $bracket_level = 0; @@ -891,7 +892,7 @@ class WebserviceRequestCore } return $fields; } - + public function setFieldsToDisplay() { // set the fields to display in the list : "full", "minimum", "field_1", "field_1,field_2,field_3" @@ -943,7 +944,7 @@ class WebserviceRequestCore } return true; } - + protected function manageFilters() { // filtered fields which can not use filters : hidden_fields @@ -953,12 +954,12 @@ class WebserviceRequestCore foreach ($this->resourceConfiguration['fields'] as $fieldName => $field) if ((!isset($this->resourceConfiguration['hidden_fields']) || (isset($this->resourceConfiguration['hidden_fields']) && !in_array($fieldName, $this->resourceConfiguration['hidden_fields'])))) - if ((!isset($field['i18n']) || + if ((!isset($field['i18n']) || (isset($field['i18n']) && !$field['i18n']))) $available_filters[] = $fieldName; else $i18n_available_filters[] = $fieldName; - + // Date feature : date=1 if (!empty($this->urlFragments['date']) && $this->urlFragments['date']) { @@ -1011,7 +1012,7 @@ class WebserviceRequestCore { // contruct SQL join for linked tables $sql_join .= 'LEFT JOIN `'._DB_PREFIX_.pSQL($this->resourceConfiguration['linked_tables'][$field]['table']).'` '.pSQL($field).' ON (main.`'.pSQL($this->resourceConfiguration['fields']['id']['sqlId']).'` = '.pSQL($field).'.`'.pSQL($this->resourceConfiguration['fields']['id']['sqlId']).'`)'."\n"; - + // construct SQL filter for linked tables foreach ($url_param as $field2 => $value) { @@ -1081,7 +1082,7 @@ class WebserviceRequestCore } } } - + if (!$this->setFieldsToDisplay()) return false; // construct SQL Sort @@ -1093,7 +1094,7 @@ class WebserviceRequestCore $sorts = explode(',', $matches[1]); else $sorts = array($this->urlFragments['sort']); - + $sql_sort .= ' ORDER BY '; foreach ($sorts as $sort) { @@ -1147,12 +1148,12 @@ class WebserviceRequestCore $filters['sql_filter'] = $sql_filter; $filters['sql_sort'] = $sql_sort; $filters['sql_limit'] = $sql_limit; - + return $filters; } - - - + + + public function getFilteredObjectList() { $objects = array(); @@ -1162,7 +1163,7 @@ class WebserviceRequestCore $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_sort']; $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_limit']; //list entities - + $tmp = new $this->resourceConfiguration['retrieveData']['className'](); $sqlObjects = call_user_func_array(array($tmp, $this->resourceConfiguration['retrieveData']['retrieveMethod']), $this->resourceConfiguration['retrieveData']['params']); if ($sqlObjects) @@ -1174,13 +1175,13 @@ class WebserviceRequestCore return $objects; } } - + public function getFilteredObjectDetails() { $objects = array(); - if (!isset($this->urlFragments['display'])) + if (!isset($this->urlFragments['display'])) $this->fieldsToDisplay = 'full'; - + // Check if Object is accessible for this/those id_shop $assoc = Shop::getAssoTables(); if (array_key_exists($this->resourceConfiguration['retrieveData']['table'] ,$assoc)) @@ -1207,15 +1208,15 @@ class WebserviceRequestCore return false; } } - + /** * Execute GET and HEAD requests - * + * * Build filter * Build fields display * Build sort * Build limit - * + * * @return boolean */ public function executeEntityGetAndHead() @@ -1226,7 +1227,7 @@ class WebserviceRequestCore $return = $this->getFilteredObjectList(); else $return = $this->getFilteredObjectDetails(); - + if (!$return) return false; else @@ -1234,20 +1235,20 @@ class WebserviceRequestCore } return true; } - + /** * Execute POST method on a PrestaShop entity - * + * * @return boolean */ protected function executeEntityPost() { return $this->saveEntityFromXml(201); } - + /** * Execute PUT method on a PrestaShop entity - * + * * @return boolean */ protected function executeEntityPut() @@ -1255,13 +1256,13 @@ class WebserviceRequestCore return $this->saveEntityFromXml(200); } - - - + + + /** * Execute DELETE method on a PrestaShop entity - * + * * @return boolean */ protected function executeEntityDelete() @@ -1290,13 +1291,13 @@ class WebserviceRequestCore $objects[] = $object; } } - + if (!empty($arr_avoid_id) || empty($ids)) { $this->setError(404, 'Id(s) not exists: '.implode(', ', $arr_avoid_id), 87); $this->_outputEnabled = true; } - else + else { $assoc = Shop::getAssoTables(); foreach ($objects as $object) @@ -1305,12 +1306,12 @@ class WebserviceRequestCore $result = $object->{$this->resourceConfiguration['objectMethods']['delete']}(); else $result = $object->delete(); - + if (!$result) $arr_avoid_id[] = $object->id; elseif (array_key_exists($this->resourceConfiguration['retrieveData']['table'] ,$assoc)) { - $sql = 'DELETE FROM `'._DB_PREFIX_.$this->resourceConfiguration['retrieveData']['table'].'_'.$assoc[$this->resourceConfiguration['retrieveData']['table']]['type'].'` + $sql = 'DELETE FROM `'._DB_PREFIX_.$this->resourceConfiguration['retrieveData']['table'].'_'.$assoc[$this->resourceConfiguration['retrieveData']['table']]['type'].'` WHERE '.$this->resourceConfiguration['fields']['id']['sqlId'].' = '.$object->id; Db::getInstance()->Execute($sql); } @@ -1326,16 +1327,16 @@ class WebserviceRequestCore } } } - + /** * Write XML output after GET and HEAD action - * + * * @return void */ - + /** * save Entity Object from XML - * + * * @param int $successReturnCode * @return boolean */ @@ -1352,9 +1353,9 @@ class WebserviceRequestCore } $xmlEntities = $xml->children(); $object = null; - + $ids = array(); - foreach ($xmlEntities as $entity) + foreach ($xmlEntities as $entity) { // To cast in string allow to check null values if ((string)$entity->id != '') @@ -1380,11 +1381,11 @@ class WebserviceRequestCore $this->setError(400, 'id is forbidden when adding a new resource', 91); return false; } - + foreach ($xmlEntities as $xmlEntity) { $attributes = $xmlEntity->children(); - + if ($this->method == 'POST') $object = new $this->resourceConfiguration['retrieveData']['className'](); elseif ($this->method == 'PUT') @@ -1402,7 +1403,7 @@ class WebserviceRequestCore foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { $sqlId = $fieldProperties['sqlId']; - + if ($fieldName == 'id') $sqlId = $fieldName; if (isset($attributes->$fieldName) && isset($fieldProperties['sqlId']) && (!isset($fieldProperties['i18n']) || !$fieldProperties['i18n'])) @@ -1423,7 +1424,7 @@ class WebserviceRequestCore $object->$sqlId = (string)$attributes->$fieldName; else $this->setError(400, 'Parameter "'.$fieldName.'" can\'t be set to the object "'.$this->resourceConfiguration['retrieveData']['className'].'"', 123); - + } elseif (isset($fieldProperties['required']) && $fieldProperties['required'] && !$fieldProperties['i18n']) { @@ -1432,7 +1433,7 @@ class WebserviceRequestCore } elseif ((!isset($fieldProperties['required']) || !$fieldProperties['required']) && Tools::property_exists($object, $sqlId)) $object->$sqlId = null; - + if (isset($fieldProperties['i18n']) && $fieldProperties['i18n']) { $i18n = true; @@ -1440,7 +1441,7 @@ class WebserviceRequestCore $object->{$fieldName}[(int)$lang->attributes()->id] = (string)$lang; } } - + if (!$this->hasErrors()) { if ($i18n && ($retValidateFieldsLang = $object->validateFieldsLang(false, true)) !== true) @@ -1512,10 +1513,10 @@ class WebserviceRequestCore return true; } } - + /** * get SQL retrieve Filter - * + * * @param string $sqlId * @param string $filterValue * @param string $tableAlias = 'main.' @@ -1565,7 +1566,7 @@ class WebserviceRequestCore $ret .= ' AND '.$tableAlias.'`'.pSQL($sqlId).'` '.(Validate::isFloat(pSQL($filterValue)) ? 'LIKE' : '=').' "'.pSQL($filterValue)."\"\n"; return $ret; } - + public function filterLanguage() { $arr_languages = array(); @@ -1617,40 +1618,40 @@ class WebserviceRequestCore $this->setError(400, 'Language ID must be numeric', 80); return false; } - + foreach ($arr_languages as $key=>$id_lang) if (!Language::getLanguage($id_lang)) unset($arr_languages[$key]); - + return $arr_languages; } - + /** - * Thanks to the (WebserviceOutputBuilder) WebserviceKey::objOutput + * Thanks to the (WebserviceOutputBuilder) WebserviceKey::objOutput * Method build the output depend on the WebserviceRequest::outputFormat * and set HTTP header parameters. - * + * * @return array with displaying informations (used in the dispatcher). */ protected function returnOutput() { $return = array(); - + // write headers $this->objOutput->setHeaderParams('Access-Time', time()) ->setHeaderParams('X-Powered-By', 'PrestaShop Webservice') ->setHeaderParams('PSWS-Version', _PS_VERSION_) ->setHeaderParams('Execution-Time', round(microtime(true) - $this->_startTime,3)); - - + + $return['type'] = strtolower($this->outputFormat); - + // write this header only now (avoid hackers happiness...) if ($this->_authenticated) { $this->objOutput->setHeaderParams('PSWS-Version', _PS_VERSION_); } - + // If Specific Management is asked if ($this->objectSpecificManagement instanceof WebserviceSpecificManagementInterface) { @@ -1663,7 +1664,7 @@ class WebserviceRequestCore $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); } } - + // for use a general output if (!$this->hasErrors() && $this->objectSpecificManagement == null) { @@ -1685,13 +1686,13 @@ class WebserviceRequestCore $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; else $type_of_view = WebserviceOutputBuilder::VIEW_LIST; - + if (in_array($this->method, array('PUT', 'POST'))) { $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; $this->fieldsToDisplay = 'full'; - } - + } + $return['content'] = $this->objOutput->getContent($this->objects, $this->schemaToDisplay, $this->fieldsToDisplay, $this->depth, $type_of_view); } catch (WebserviceException $e) { if ($e->getType() == WebserviceException::DID_YOU_MEAN) @@ -1703,7 +1704,7 @@ class WebserviceRequestCore } } } - + // if the output is not enable, delete the content // the type content too if (!$this->_outputEnabled) @@ -1713,18 +1714,18 @@ class WebserviceRequestCore if (isset($return['content'])) unset($return['content']); } - + elseif (isset($return['content'])) $this->objOutput->setHeaderParams('Content-Sha1', sha1($return['content'])); - - // if errors happends when creating returned xml, + + // if errors happends when creating returned xml, // the usual xml content is replaced by the nice error handler content if ($this->hasErrors()) { $this->_outputEnabled = true; $return['content'] = $this->objOutput->getErrors($this->errors); } - + if (!isset($return['content']) || strlen($return['content']) <= 0) { $this->objOutput->setHeaderParams('Content-Type', ''); diff --git a/docs/csv_import/.htaccess b/docs/csv_import/.htaccess new file mode 100755 index 000000000..18aba5838 --- /dev/null +++ b/docs/csv_import/.htaccess @@ -0,0 +1 @@ +Allow from ALL \ No newline at end of file diff --git a/docs/csv_import/adresses_import.csv b/docs/csv_import/adresses_import.csv new file mode 100644 index 000000000..54bb4054d --- /dev/null +++ b/docs/csv_import/adresses_import.csv @@ -0,0 +1,4 @@ +ID;Alias*;Active (0/1);Customer e-mail;Manufacturer;Supplier;Company;Lastname*;Firstname*;Address 1*;Address 2;Postcode* / Zipcode*;City*;Country*;State;Other;Phone;Mobile Phone;VAT number +1;My Adress;1;johndoe@prestashop.com;;;;Doe;John;16, Main street;2nd floor;75000;PARIS ;France;;;140138844;; +2;My work;1;johndoe@prestashop.com;;;My Company;Doe;John;535, Baker street;;13000;Marseile;France;;;235445588;; +3;My work;0;;Apple Computer, Inc;;;Jobs;Steve;1 Infinite Loop;;95014;CUPERTINO;United States;California;;(800) 275-2273;; \ No newline at end of file diff --git a/docs/csv_import/categories_import.csv b/docs/csv_import/categories_import.csv new file mode 100644 index 000000000..60239991b --- /dev/null +++ b/docs/csv_import/categories_import.csv @@ -0,0 +1,4 @@ +ID;Active (0/1);Name*;Parent Category;Description;Meta-title;Meta-keywords;Meta-description;URL rewritten;Image URL +2;1;iPods;Home;Now that you can buy movies from the iTunes Store and sync them to your iPod, the whole world is your theater.;;;;music-ipods;http://youlinktotheimage.com/img1000.jpg +3;1;Accessories;Home;Wonderful accessories for your iPod;;;;accessories-ipod;http://youlinktotheimage.com/img1001.jpg +4;1;Laptops;Home;The latest Intel processor, a bigger hard drive, plenty of memory, and even more new features all fit inside just one liberating inch. The new Mac laptops have the performance, power, and connectivity of a desktop computer. Without the desk part.;Apple laptops;Apple laptops MacBook Air;Powerful and chic Apple laptops;laptops;http://youlinktotheimage.com/img1002.jpg \ No newline at end of file diff --git a/docs/csv_import/combinations_import.csv b/docs/csv_import/combinations_import.csv new file mode 100644 index 000000000..3c0a370a4 --- /dev/null +++ b/docs/csv_import/combinations_import.csv @@ -0,0 +1,3 @@ +Product ID*;Options (Group:Value)*;Reference;Supplier reference;EAN13;UPC;Wholesale price;Price;Ecotax;Quantity;Weight;Default +1;"Color:Blue, Disk Space:16GO;";958456;254644;;;;41;;50;; +1;"Color:pINK, Disk Space:8GO;";958456;254644;;;;;;;; \ No newline at end of file diff --git a/docs/csv_import/customers_import.csv b/docs/csv_import/customers_import.csv new file mode 100644 index 000000000..527f2bfce --- /dev/null +++ b/docs/csv_import/customers_import.csv @@ -0,0 +1,3 @@ +ID;Active (0/1);Gender ID (Mr=1, Ms=2, else 9);E-mail*;Password*;Birthday;Lastname*;Firstname*;Newletter (0/1);Opt-in (0/1) +1;1;1;johndoe@prestashop.com;#res152EDRF;sous quelle forme ? ;Doe;John;1;1 +2;1;2;mariedoe@prestashop.com;58@ret26#;sous quelle forme ? ;Doe;Marie;0;1 \ No newline at end of file diff --git a/docs/csv_import/manufacturer_import.csv b/docs/csv_import/manufacturer_import.csv new file mode 100644 index 000000000..e91c6b113 --- /dev/null +++ b/docs/csv_import/manufacturer_import.csv @@ -0,0 +1,3 @@ +ID;Active (0/1);Name*;Description;Short description;Meta-title;Meta-keywords;Meta-description +1;1;Apple Computer, Inc;;;;; +2;1;Shure Incorporated;;;;; \ No newline at end of file diff --git a/docs/csv_import/products_import.csv b/docs/csv_import/products_import.csv new file mode 100644 index 000000000..7202a63ef --- /dev/null +++ b/docs/csv_import/products_import.csv @@ -0,0 +1,3 @@ +ID;Active (0/1);Name*;Categories (x,y,z,...);Price tax excl. Or Price tax excl;Tax rules id;Wholesale price;On sale (0/1);Discount amount;Discount percent;Discount from (yyy-mm-dd);Discount to (yyy-mm-dd);Reference #;Supplier reference #;Supplier;Manufacturer;EAN13;UPC;Ecotax;Weight;Quantity;Short description;Description;Tags (x,y,z,...);Meta-title;Meta-keywords;Meta-description;URL rewritten;Text when in-stock;Text if back-order allowed;Image URLs (x,y,z,...);Feature;Only available online +1;1;iPod Nano;Home, iPods;49;1;;1;;;;;92458844;54778855;AppleStore;Apple Computer, Inc;;;;0.5;800;New design. New features. Now i….;Curved ahead of the curve. For those about to rock, we give you nine amazing colors. But that's only part of the story. Feel the curved, all-aluminum and glass de...;apple, ipod, nano;;;;ipod-nano;In stock;;http://youdomain.com/img.jpg, http://yourdomain.com/img1.jpg;; +2;1;iPod shuffle;Home, iPods;66.05;1;79;1;;;;;92458845;54778855;AppleStore;Apple Computer, Inc;;;;0;500;iPod shuffle, the world’s most wearabl….;;ipod, shuffle;;;;ipod-shuffle;In stock;;http://youdomain.com/img25.jpg, http://yourdomain.com/img30.jpg;; \ No newline at end of file diff --git a/docs/csv_import/suppliers_import.csv b/docs/csv_import/suppliers_import.csv new file mode 100644 index 000000000..b43d7a3a7 --- /dev/null +++ b/docs/csv_import/suppliers_import.csv @@ -0,0 +1,3 @@ +ID;Active (0/1);Name*;Description;Short description;Meta-title;Meta-keywords;Meta-description +1;1;Applestore;;;;; +2;1;Shure Online Store;;;;; \ No newline at end of file diff --git a/install-dev/index.php b/install-dev/index.php index f9ffb4191..3dfff7b86 100644 --- a/install-dev/index.php +++ b/install-dev/index.php @@ -730,7 +730,7 @@ if ($lm->getIncludeTradFilename())
-
+