From 6629c19bd2eaf2cca6ef384cc6d39d69afbd4aba Mon Sep 17 00:00:00 2001 From: TL Date: Fri, 28 Jan 2022 15:25:52 +0800 Subject: [PATCH 01/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 1 + composer.lock | 719 +++++++++++++----- upload/admin/controller/tool/gd_import.php | 171 +++++ .../admin/language/zh-cn/tool/gd_import.php | 36 + upload/admin/model/tool/gd_import.php | 570 ++++++++++++++ .../admin/view/template/tool/gd_import.twig | 146 ++++ 6 files changed, 1443 insertions(+), 200 deletions(-) create mode 100644 upload/admin/controller/tool/gd_import.php create mode 100644 upload/admin/language/zh-cn/tool/gd_import.php create mode 100644 upload/admin/model/tool/gd_import.php create mode 100644 upload/admin/view/template/tool/gd_import.twig diff --git a/composer.json b/composer.json index ef6fa1ea..7baaa6ab 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,7 @@ "maximebf/debugbar": "^1.14", "nesbot/carbon": "2.*", "overtrue/socialite": "^2.0", + "phpoffice/phpspreadsheet": "^1.19", "swiftmailer/swiftmailer": "5.*", "symfony/var-dumper": "4.*", "twig/twig": "1.*", diff --git a/composer.lock b/composer.lock index f7acb77a..800d594d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c68ba4ed002ee2323f136bf9a3637d75", + "content-hash": "f57fb8a2ef8ed1f053245e55afcfc320", "packages": [ { "name": "abraham/twitteroauth", @@ -286,17 +286,17 @@ "time": "2020-05-29T07:19:59+00:00" }, { - "name": "doctrine/lexer", - "version": "1.2.1", + "name": "ezyang/htmlpurifier", + "version": "v4.14.0", "source": { "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75", + "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75", "shasum": "", "mirrors": [ { @@ -306,130 +306,41 @@ ] }, "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan": "^0.11.8", - "phpunit/phpunit": "^8.2" + "php": ">=5.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" + "psr-0": { + "HTMLPurifier": "library/" }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2020-05-25T17:44:05+00:00" - }, - { - "name": "egulias/email-validator", - "version": "2.1.22", - "source": { - "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5", - "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } + "files": [ + "library/HTMLPurifier.composer.php" + ], + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" ] }, - "require": { - "doctrine/lexer": "^1.0.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.10" - }, - "require-dev": { - "dominicsayers/isemail": "^3.0.7", - "phpunit/phpunit": "^4.8.36|^7.5.15", - "satooshi/php-coveralls": "^1.0.1" - }, - "suggest": { - "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Egulias\\EmailValidator\\": "src" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "LGPL-2.1-or-later" ], "authors": [ { - "name": "Eduardo Gulias Davis" + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" } ], - "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", "keywords": [ - "email", - "emailvalidation", - "emailvalidator", - "validation", - "validator" + "html" ], - "time": "2020-09-26T15:48:38+00:00" + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0" + }, + "time": "2021-12-25T01:21:49+00:00" }, { "name": "filp/whoops", @@ -1112,6 +1023,202 @@ "abandoned": "scssphp/scssphp", "time": "2014-07-07T01:51:39+00:00" }, + { + "name": "maennchen/zipstream-php", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58", + "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "myclabs/php-enum": "^1.5", + "php": ">= 7.1", + "psr/http-message": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "ext-zip": "*", + "guzzlehttp/guzzle": ">= 6.3", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": ">= 7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/master" + }, + "funding": [ + { + "url": "https://opencollective.com/zipstream", + "type": "open_collective" + } + ], + "time": "2020-05-30T13:11:16+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22", + "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.1" + }, + "time": "2021-06-29T15:32:53+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576", + "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "phpcompatibility/php-compatibility": "^9.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.0" + }, + "time": "2021-07-01T19:01:15+00:00" + }, { "name": "maximebf/debugbar", "version": "v1.16.3", @@ -1297,6 +1404,72 @@ "homepage": "https://github.com/maxmind/web-service-common-php", "time": "2020-05-06T14:07:26+00:00" }, + { + "name": "myclabs/php-enum", + "version": "1.7.7", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "d178027d1e679832db9f38248fcc7200647dc2b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/d178027d1e679832db9f38248fcc7200647dc2b7", + "reference": "d178027d1e679832db9f38248fcc7200647dc2b7", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.7.7" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2020-11-14T18:14:52+00:00" + }, { "name": "nesbot/carbon", "version": "2.36.1", @@ -1509,6 +1682,116 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.19.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "a9ab55bfae02eecffb3df669a2e19ba0e2f04bbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a9ab55bfae02eecffb3df669a2e19ba0e2f04bbf", + "reference": "a9ab55bfae02eecffb3df669a2e19ba0e2f04bbf", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.13", + "maennchen/zipstream-php": "^2.1", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": "^7.2 || ^8.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "dompdf/dompdf": "^1.0", + "friendsofphp/php-cs-fixer": "^2.18", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^8.0", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^0.12.82", + "phpstan/phpstan-phpunit": "^0.12.18", + "phpunit/phpunit": "^8.5", + "squizlabs/php_codesniffer": "^3.5", + "tecnickcom/tcpdf": "^6.3" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", + "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.19.0" + }, + "time": "2021-10-31T15:09:20+00:00" + }, { "name": "psr/container", "version": "1.0.0", @@ -1564,6 +1847,125 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -2066,89 +2468,6 @@ ], "time": "2020-07-14T12:35:20+00:00" }, - { - "name": "symfony/polyfill-iconv", - "version": "v1.18.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "6c2f78eb8f5ab8eaea98f6d414a5915f2e0fce36" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/6c2f78eb8f5ab8eaea98f6d414a5915f2e0fce36", - "reference": "6c2f78eb8f5ab8eaea98f6d414a5915f2e0fce36", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-iconv": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.18-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Iconv\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Iconv extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "iconv", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-07-14T12:35:20+00:00" - }, { "name": "symfony/polyfill-intl-idn", "version": "v1.18.0", @@ -3084,5 +3403,5 @@ "ext-openssl": "^7.1" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.1.0" } diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php new file mode 100644 index 00000000..fc445cbc --- /dev/null +++ b/upload/admin/controller/tool/gd_import.php @@ -0,0 +1,171 @@ +load->language('tool/gd_import'); + + $this->document->setTitle($this->language->get('heading_title')); + + $this->getForm(); + } + + public function upload() { + $this->load->language('tool/gd_import'); + $json = []; + if (!$this->validateForm()) { + if (isset($this->error['warning'])) { + $json['error'] = $this->error['warning']; + } elseif (isset($this->error['csvfile'])) { + $json['error'] = $this->error['csvfile']; + } + } + + if (!$json) { + // Sanitize the filename + $filename = 'gd_' . time();//basename(html_entity_decode(iconv('utf-8', 'gbk//IGNORE', $this->request->files['csvfile']['name']), ENT_QUOTES, 'UTF-8')); + + move_uploaded_file($this->request->files['csvfile']['tmp_name'], DIR_STORAGE . 'upload/' . $filename); + $file = DIR_STORAGE . 'upload/' . $filename; + + try { + $this->load->model('tool/gd_import'); + $result = $this->model_tool_gd_import->upload($file); + } catch (\Exception $e) { + throw $e; + $json['error'] = $e->getMessage(); + } + + if (!$json) { + $json['count'] = $result; + } + } + $this->response->renderJson($json); + } + + public function import() { + $this->load->language('tool/gd_import'); + $json = []; + try { + $this->load->model('tool/gd_import'); + $this->model_tool_gd_import->import($this->request->get['index']); + } catch (\Exception $e) { + $json['error'] = $e->getMessage(); + } + + $this->jsonOutput($json); + } + + public function download() { + $this->load->model('tool/gd_import'); + $this->model_tool_gd_import->download('product'); + + } + + protected function validateForm() { + if (!$this->user->hasPermission('modify', 'tool/gd_import')) { + $this->error['warning'] = $this->language->get('error_permission'); + } + + if (empty($this->request->files['csvfile']['name']) || !is_file($this->request->files['csvfile']['tmp_name'])) { + $this->error['csvfile'] = $this->language->get('error_csvfile'); + } else { + $post_max_size = $this->return_bytes(ini_get('post_max_size')); + $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); + + if ($this->request->files['csvfile']['size'] > $post_max_size) { + $this->error['csvfile'] = sprintf($this->language->get('error_post_max_size'), ini_get('post_max_size')); + } + + if ($this->request->files['csvfile']['size'] > $upload_max_filesize) { + $this->error['csvfile'] = sprintf($this->language->get('error_upload_max_filesize'), ini_get('upload_max_filesize')); + } + + // Sanitize the filename + $filename = basename(html_entity_decode($this->request->files['csvfile']['name'], ENT_QUOTES, 'UTF-8')); + + // Allowed file extension typesx + if (strtolower(substr(strrchr($filename, '.'), 1)) != 'xlsx') { + $this->error['csvfile'] = $this->language->get('error_filetype'); + } + } + + return !$this->error; + } + + private function return_bytes($val) + { + $val = trim($val); + + switch (strtolower(substr($val, -1))) { + case 'm': $val = (int)substr($val, 0, -1) * 1048576; break; + case 'k': $val = (int)substr($val, 0, -1) * 1024; break; + case 'g': $val = (int)substr($val, 0, -1) * 1073741824; break; + case 'b': + switch (strtolower(substr($val, -2, 1))) { + case 'm': $val = (int)substr($val, 0, -2) * 1048576; break; + case 'k': $val = (int)substr($val, 0, -2) * 1024; break; + case 'g': $val = (int)substr($val, 0, -2) * 1073741824; break; + default : break; + } break; + default: break; + } + return $val; + } + + protected function getForm() { + $data['text_form'] = $this->language->get('heading_title'); + + if (isset($this->error['warning'])) { + $data['error_warning'] = $this->error['warning']; + } else { + $data['error_warning'] = ''; + } + + if (isset($this->error['csvfile'])) { + $data['error_csvfile'] = $this->error['csvfile']; + } else { + $data['error_csvfile'] = ''; + } + + if (isset($this->session->data['success'])) { + $data['success'] = $this->session->data['success']; + + unset($this->session->data['success']); + } else { + $data['success'] = ''; + } + + $data['breadcrumbs'] = array(); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_home'), + 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token']) + ); + + $data['breadcrumbs'][] = array( + 'text' => $this->language->get('heading_title'), + 'href' => $this->url->link('tool/gd_import', 'user_token=' . $this->session->data['user_token']) + ); + + $data['action'] = $this->url->link('tool/gd_import/upload', 'user_token=' . $this->session->data['user_token']); + $data['download_href'] = $this->url->link('tool/gd_import/download', 'user_token=' . $this->session->data['user_token']); + + if (isset($this->request->post['csvfile'])) { + $data['csvfile'] = $this->request->post['csvfile']; + } else { + $data['sort_order'] = ''; + } + + $data['user_token'] = $this->session->data['user_token']; + + $data['header'] = $this->load->controller('common/header'); + $data['column_left'] = $this->load->controller('common/column_left'); + $data['footer'] = $this->load->controller('common/footer'); + + $this->response->setOutput($this->load->view('tool/gd_import', $data)); + } +} diff --git a/upload/admin/language/zh-cn/tool/gd_import.php b/upload/admin/language/zh-cn/tool/gd_import.php new file mode 100644 index 00000000..66e14b89 --- /dev/null +++ b/upload/admin/language/zh-cn/tool/gd_import.php @@ -0,0 +1,36 @@ + + * @created 2016-12-14 11:22:04 + * @modified 2016-12-14 17:37:17 + */ + +// Heading +$_['heading_title'] = '商品导入导出'; + +// Text +$_['text_success'] = '成功:您已成功导入您的数据'; +$_['text_upload_confirm'] = '确认开始导入?'; + +// Entry +$_['entry_download'] = '商品导出'; +$_['entry_file'] = '导入文件'; + +// Button labels +$_['button_download'] = '导出商品'; +$_['button_import'] = '导入'; + +$_['help_template'] = '请输入要导出的商品范围,然后点击导出商品按钮'; +$_['help_file'] = '导入请使用Excel2007格式(扩展名为.xlsx),导入数据表格式参见导出的excel格式。'; + +//Error +$_['error_permission'] = '警告: 您没有权限修改导入导出!'; +$_['error_upload'] = '导入的电子表格无效或其中的数据格式错误!'; +$_['error_post_max_size'] = '文件大小超过 %s (查看php设置 \'post_max_size\')'; +$_['error_upload_max_filesize'] = '文件大小超过 %s (查看php设置 \'upload_max_filesize\')'; +$_['error_filetype'] = '文件类型错误,请使用Excel2007格式(扩展名为.xlsx)文件导入'; +$_['error_filed_required'] = '表%s的第%s行的字段“%s”必填!'; +$_['error_header_need_columns'] = 'Excel的表%s缺少字段:%s!'; +$_['error_file_required'] = '请选择文件'; diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php new file mode 100644 index 00000000..08eb1f91 --- /dev/null +++ b/upload/admin/model/tool/gd_import.php @@ -0,0 +1,570 @@ + + * @created 2018-07-26 11:22:04 + * @modified 2018-07-26 17:37:17 + */ + +class ModelToolGdImport extends Model { + /** + * 格式要求: + * 1、每个模板的第一个sheet必须为主表,其他sheet为附表 + * 2、每个sheet的第一个字段必须主键(主表)或外键(附表) + * 3、每个字段的code必须与数据库字段名称一致 + * 4、每个sheet的key必须与创建方法中使用的key一致 + * 5、如果主表涉及多语言的话,第二个表为主表的描述表 + * @var array + */ + private $template_category = array( + 'category' => array( + array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false,), + array('code' => 'top', 'name' => 'Top', 'cell_width' => 8, 'require' => false,), + array('code' => 'column', 'name' => 'Column', 'cell_width' => 8, 'require' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), + array('code' => 'image', 'name' => 'images', 'cell_width' => 28,'require' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false,) + ), + 'category_description' => array( + array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), + ), + ); + private $template_base = array( + 'filter_groups' => array( + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'filters' => array( + array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'options' => array( + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'option_values' => array( + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'customer_groups' => array( + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 28,'require' => false,) + ), + 'attribute_groups' => array( + array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'attributes' => array( + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ) + ); + private $template_product = array( + 'product' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'categorys', 'name' => 'Categories', 'cell_width' => 8, 'require' => false,), + array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false,), + array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false,), + array('code' => 'upc', 'name' => 'UPC', 'cell_width' => 8, 'require' => false,), + array('code' => 'ean', 'name' => 'EAN', 'cell_width' => 8, 'require' => false,), + array('code' => 'jan', 'name' => 'JAN', 'cell_width' => 8, 'require' => false,), + array('code' => 'isbn', 'name' => 'ISBN', 'cell_width' => 8, 'require' => false,), + array('code' => 'mpn', 'name' => 'MPN', 'cell_width' => 8, 'require' => false,), + array('code' => 'location', 'name' => 'Location', 'cell_width' => 8, 'require' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), + array('code' => 'model', 'name' => 'Model', 'cell_width' => 8, 'require' => true,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false,), + array('code' => 'shipping', 'name' => 'Require Shipping','cell_width' => 8, 'require' => true,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => true,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false,), + array('code' => 'date_available', 'name' => 'Date Available', 'cell_width' => 18,'require' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false,), + array('code' => 'weight_class_id', 'name' => 'Weight Unit', 'cell_width' => 8, 'require' => false,), + array('code' => 'length', 'name' => 'Length', 'cell_width' => 8, 'require' => false,), + array('code' => 'width', 'name' => 'Width', 'cell_width' => 8, 'require' => false,), + array('code' => 'height', 'name' => 'Height', 'cell_width' => 8, 'require' => false,), + array('code' => 'length_class_id', 'name' => 'Length Unit', 'cell_width' => 8, 'require' => false,), + array('code' => 'tax_class_id', 'name' => 'Tax Class ID', 'cell_width' => 8, 'require' => false,), + array('code' => 'viewed', 'name' => 'Viewed', 'cell_width' => 8, 'require' => false,), + array('code' => 'stock_status_id', 'name' => 'Stock Status ID', 'cell_width' => 8, 'require' => false,), + array('code' => 'relateds', 'name' => 'Related IDs', 'cell_width' => 8, 'require' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false,), + array('code' => 'minimum', 'name' => 'Minimum', 'cell_width' => 8, 'require' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false,) + ), + 'product_description' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), + array('code' => 'tag', 'name' => 'Tags', 'cell_width' => 28,'require' => false,) + ), + 'product_image' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'product_option' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => false,), + array('code' => 'value', 'name' => 'Value', 'cell_width' => 18,'require' => false,), + array('code' => 'required', 'name' => 'Required', 'cell_width' => 18,'require' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), + array('code' => 'price_prefix', 'name' => 'Price Prefix', 'cell_width' => 8, 'require' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), + array('code' => 'points_prefix', 'name' => 'Points Prefix', 'cell_width' => 8, 'require' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false,), + array('code' => 'weight_prefix', 'name' => 'Weight Prefix', 'cell_width' => 8, 'require' => false,) + ), + 'product_attribute' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'text', 'name' => 'Text', 'cell_width' => 18,'require' => true,), + ), + 'product_special' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false,), + ), + 'product_discount' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false,), + ), + 'product_reward' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), + ), + 'product_related' => array( + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'related_id', 'name' => 'Related Product ID','cell_width' => 8, 'require' => true,), + ), + ); + private $data_start_line = 3; // 正式数据从第几行开始 + + public function getCell(&$worksheet,$row,$col,$default_val='') { + $row += 1; // we use 0-based, PHPExcel used 1-based row index + return ($worksheet->cellExistsByColumnAndRow($col,$row)) ? $worksheet->getCellByColumnAndRow($col,$row)->getValue() : $default_val; + } + + public function formatData($data, $template, $table_name) { + $columns = $template[$table_name]; + $header = array_shift($data); // 第一行是表头 + $diff = array_diff(array_column($columns, 'name'), $header); + if ($diff) { + throw new \Exception(sprintf(t('error_header_need_columns'), implode(',', $diff))); // excel表缺少字段$diff + } + + // 跳过表头和正问之间的描述和demo行 + for ($i = 2; $i < $this->data_start_line; $i++) { + array_shift($data); + } + + $result = []; + $name_code_maps = array_column($columns, 'code', 'name'); + foreach ($data as $line) { + //$line = array_combine($map, $line); + $row = []; + foreach ($line as $key => $cell) { + if (isset($name_code_maps[$header[$key]])) { + $row[$name_code_maps[$header[$key]]] = $cell; + } + } + $result[] = $row; + } + + return $result; + } + + public function validate($datas, $type) { + foreach ($datas as $index => $data) { + $columns = $this->{'template_' . $type}[$index]; + $required_map = array_column($columns, 'require', 'code'); + $field_name_map = array_column($columns, 'name', 'code'); + + foreach ($data as $index => $item) { + foreach ($item as $code => $value) { + if ($required_map[$code] && empty($value)) { // 如果必填且$value为空 + throw new \Exception(sprintf(t('error_filed_required'), $index, $index + $this->data_start_line, $field_name_map[$code])); // $index为0的数据实际上是excel第3行 + } + } + } + } + } + + public function validateServiceLogic($data) { + foreach ($data as $index => $item) { + if (!$this->isTrackingCode($item['platform'],$item['tracking_code'])) { + throw new \Exception(sprintf($this->language->get('error_tracking_code'), $index + $this->data_start_line , $item['tracking_code'])); + } + $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE order_id = '" . $item['order_id'] . "'"); + if (!$query->num_rows) { + throw new \Exception(sprintf($this->language->get('error_order_id'), $index + $this->data_start_line , $item['order_id'])); + } else { + if (!in_array(\Services\StateMachine::SHIPPED, array_keys(\Services\StateMachine::getInstance($item['order_id'])->nextBackendStatuses()))) { + throw new \Exception(sprintf($this->language->get('error_order_status'), $index + $this->data_start_line , $item['order_id'])); + } + } + // 验证某个订单的某个快递单号数据是否已经存在 + foreach ($data as $index => $item) { + $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_shippingtrack` WHERE order_id = '" . $item['order_id'] . "' AND tracking_number = '" . $item['tracking_number'] . "' AND tracking_code = '" . $item['tracking_code'] . "'"); + if ($query->num_rows) { + throw new \Exception(sprintf(t('error_tracking_number_exist'), $index + $this->data_start_line)); + } + } + } + // 验证Excel中快递单号是否重复 + $data_all = array_map(function ($item){ + return $item['order_id'] . '||' . $item['tracking_number'] . '||' . $item['tracking_code']; + }, $data); + $values_count = array_count_values($data_all); + foreach ($values_count as $key => $value) { + if ($value > 1) { + $ott_arr = explode('||', $key); + throw new \Exception(sprintf(t('error_tracking_number_repeate'), $ott_arr[0], $ott_arr[1], $ott_arr[2])); + } + } + } + + function download($type) { + // set appropriate timeout limit + set_time_limit( 0 ); + ini_set('memory_limit', '512M'); + + // create a new workbook + $workbook = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); + + // set default font name and size + $workbook->getDefaultStyle()->getFont()->setName('Arial'); + $workbook->getDefaultStyle()->getFont()->setSize(10); + $workbook->getDefaultStyle()->getAlignment()->setIndent(1); + + // creating the worksheet + $i = 0; + foreach ($this->{'template_' . $type} as $table => $columns) { + if ($i > 0) { + $workbook->createSheet(); + } + $workbook->setActiveSheetIndex($i++); + $worksheet = $workbook->getActiveSheet(); + $worksheet->setTitle($table); +// $func = $this->convertUnderline('get_' . $key); + $this->populateWorksheet($worksheet, [], $columns, $table, $type); + $worksheet->freezePaneByColumnAndRow( 1, 2 ); + } + + $workbook->setActiveSheetIndex(0); + + $datetime = date('Y-m-d'); + //header('Content-Type: application/vnd.ms-excel'); + //header('Content-Disposition: attachment;filename="GDExportImport_products_'.$datetime.'.xls"'); + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header('Content-Disposition: attachment;filename="GDExportImport_'.$type.'_'.$datetime.'.xlsx"'); + header('Cache-Control: max-age=0'); + + // If you're serving to IE over SSL, then the following may be needed + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified + header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 + header('Pragma: public'); // HTTP/1.0 + + //$writer = PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xls'); + $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx'); + if(ob_get_length()){ + ob_clean(); + } + + $writer->save('php://output'); + } + /** + * @param $worksheet + * @param $data 要写入工作表的数据, 每个记录中的字段顺序必须和$template一致 + * @param $template 工作表的表头,如:array(array('key'=>'product_id','name'=>'Product ID','format'=>'box'),array('key'=>'model','name'=>'Model ','format'=>'box')),其中value的实际长度即为excel列的宽度,需要宽一点的直接加空格 + */ + private function populateWorksheet(&$worksheet, $data, $columns, $tableName) + { + // Set the column widths + $j = 1; + foreach ($columns as $item) { + $worksheet->getColumnDimensionByColumn($j++)->setWidth($item['cell_width']); + } + + // The heading row + $i = 1; + $j = 1; + foreach ($columns as $item) { + $this->setCell($worksheet, $i, $j++, $item['name']); + } + $i++; + $j = 1; + foreach ($columns as $item) { + $this->setCell($worksheet, $i, $j++, t('des_' . $tableName . '_' . $item['code'])); + } + $worksheet->getRowDimension($i)->setRowHeight(30); + + // The actual product discounts data + $i++; + foreach ($data as $row) { + $worksheet->getRowDimension($i)->setRowHeight(13); + $j = 1; + foreach ($columns as $item) { + $cell_value = $row[$item['code']]; + if ($item['type'] == 'html') { + $cell_value = html_entity_decode($cell_value,ENT_QUOTES,'UTF-8'); + } + $this->setCell($worksheet, $i, $j++, $cell_value, $this->format[$item['format']]); + } + $i++; + } + } + + private function setCell(&$worksheet, $row/*1-based*/, $col/*0-based*/, $val, $style=NULL) { + $sel_index = $this->IntToChr($col) . $row; + $worksheet->setCellValueExplicit($sel_index, $val, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + } + + private function IntToChr($index) { + $index--; + $str = ''; + if (floor($index / 26) > 0) { + $str .= $this->IntToChr(floor($index / 26)); + } + return $str . chr($index % 26 + 65); + } + + public function upload($file_path) { + $this->load->language('tool/gd_import'); + + // parse uploaded spreadsheet file + $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($file_path); + $objReader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); + $objReader->setReadDataOnly(true); + $reader = $objReader->load($file_path); + + $type = 'product'; + $data = []; + $i = 0; + foreach ($this->{'template_' . $type} as $index => $item) { + $data[$index] = $this->getSheet($reader, $type, $index, $i); + $i++; + } + $this->validate($data, $type); + //$this->validateServiceLogic($data); + $data = $this->refactorData($data); + $data = $this->perfectData($data, $type); + dd($data); + $this->cache->set('gd_import' . $this->user->getId(), $data); + + return count($data); + } + + /** + * 将数据重组为调用model层原生方法所需的结构 + * @param $data + * @return array|mixed + */ + public function refactorData($data) { + $result = array_shift($data); + $array_keys = array_keys(current($result)); + $primary_id_name = array_shift($array_keys); + $result = array_column($result, null, $primary_id_name); + foreach ($data as $table => $items) { + foreach ($items as $item) { + if (isset($item['language_id'])) { + $result[$item[$primary_id_name]][$table][$item['language_id']] = $item; + } else { + $result[$item[$primary_id_name]][$table][] = $item; + } + } + } + return $result; + } + + /** + * 将数据补充其他必要数据,比如date_added,date_modify等调用创建函数必须要,但是excel导入没有提供的字段。使数据达到可以调用model层创建方法的标准 + * @param $data + * @return array|mixed + */ + public function perfectData($data, $type) { + $result = []; + switch ($type) { + case 'product': + foreach ($data as $item) { + $item['date_added'] = date($this->language->get('datetime_format')); + $item['date_added'] = date($this->language->get('datetime_format')); + if ($item['categorys']) { + $item['product_category'] = array_map(function ($item) { + return trim($item); + }, explode(',', $item['categorys'])); + } + if ($item['filters']) { + $item['product_filter'] = array_map(function ($item) { + return trim($item); + }, explode(',', $item['filters'])); + } + + $result[] = $item; + } + break; + case 'category': + foreach ($data as $item) { + $item['date_added'] = date($this->language->get('datetime_format')); + $item['date_added'] = date($this->language->get('datetime_format')); + } + break; + case 'option': + brake; + case 'attribute': + brake; + case 'manufacturer': + brake; + case 'customer_groups': + break; + } + return $result; + } + + public function import($index) { + $type = 'product'; + $data = $this->cache->get('gd_import' . $this->user->getId()); + if ($index >= count($data)) { + throw new \Exception('data not exist!'); + } + switch ($type) { + case 'product': + $this->load->model('catalog/product'); + foreach ($data as $item) { + if (is_numeric($item['product_id'])) { + $this->model_catalog_product->addProduct($item); + } else { + $this->model_catalog_product->updateProduct($item['product_id'], $item); + } + } + break; + case 'category': + $this->load->model('catalog/category'); + foreach ($data as $item) { + if (is_numeric($item['category_id'])) { + $this->model_catalog_category->addCategory($item); + } else { + $this->model_catalog_product->updateCategory($item['product_id'], $item); + } + } + break; + case 'option': + brake; + case 'attribute': + brake; + case 'manufacturer': + brake; + case 'customer_groups': + break; + } + $this->createData($data[$index]); + } + + /** + * @param $reader + * @param $index // 从0开始,0为第一个sheet + * @throws Exception + */ + private function getSheet($reader, $type, $table_index, $index, $transpose = false) { + if ($reader->getSheetCount() <= $index) { + throw new \Exception($this->language->get('error_sheet_not_exist')); + } + + $data = $reader->getSheet($index); + $result = []; + $row_count = $data->getHighestRow(); + $col_count = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($data->getHighestColumn()); + if ($transpose) { + for ($j = 1; $j <= $col_count; $j++) { + $row = []; + for ($i = 0; $i < $row_count; $i++) { + $cell_value = trim($this->getCell($data, $i, $j)); + $row[] = $cell_value; + } + $result[] = $row; + } + } else { + for ($i = 0; $i < $row_count; $i++) { + $row = []; + for ($j = 1; $j <= $col_count; $j++) { + $cell_value = trim($this->getCell($data, $i, $j)); + $row[] = $cell_value; + } + $result[] = $row; + } + } + + $result = $this->utf8($result); + $result = $this->formatData($result, $this->{'template_' . $type}, $table_index); + return $result; + } + + private function utf8($data) { + if (is_array($data)) { + foreach ($data as $item) { + $this->utf8($item); + } + + } else { + $encode = mb_detect_encoding($data, array("GB2312","GBK","BIG5","ASCII","UTF-8")); + if( $encode != "UTF-8") { + $data = mb_convert_encoding($data, 'UTF-8', $encode); + } + } + + return $data; + } +} diff --git a/upload/admin/view/template/tool/gd_import.twig b/upload/admin/view/template/tool/gd_import.twig new file mode 100644 index 00000000..d16fbdbf --- /dev/null +++ b/upload/admin/view/template/tool/gd_import.twig @@ -0,0 +1,146 @@ +{{ header }}{{ column_left }} +
+ +
{% if error_warning %} +
{{ error_warning }} + +
+ {% endif %} + {% if success %} +
{{ success }} + +
+ {% endif %} +
+
+

{{ heading_title }}

+
+
+
+
+ +
+ {{ button_download }} +
{{ help_template }}
+
+
+ +
+ +
+ +
+ +
{{ help_file }}
+
+
+
+
+ +
+
+
+ + +
+
+
+
+ +{{ footer }} -- Gitee From cd20b4b5bd378008b7bc35cd6b61c7eea149c534 Mon Sep 17 00:00:00 2001 From: TL Date: Thu, 10 Feb 2022 17:08:40 +0800 Subject: [PATCH 02/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/model/tool/gd_import.php | 154 +++++++++++++------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index 08eb1f91..aaa7034e 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -1,4 +1,7 @@ array( array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true,), array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false,), @@ -40,7 +43,7 @@ class ModelToolGdImport extends Model { array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), ), ); - private $template_base = array( + protected $template_base = array( 'filter_groups' => array( array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), @@ -89,7 +92,7 @@ class ModelToolGdImport extends Model { array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ) ); - private $template_product = array( + protected $template_product = array( 'product' => array( array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), array('code' => 'categorys', 'name' => 'Categories', 'cell_width' => 8, 'require' => false,), @@ -192,17 +195,19 @@ class ModelToolGdImport extends Model { ); private $data_start_line = 3; // 正式数据从第几行开始 - public function getCell(&$worksheet,$row,$col,$default_val='') { + public function getCell(&$worksheet, $row, $col, $default_val = '') + { $row += 1; // we use 0-based, PHPExcel used 1-based row index - return ($worksheet->cellExistsByColumnAndRow($col,$row)) ? $worksheet->getCellByColumnAndRow($col,$row)->getValue() : $default_val; + return ($worksheet->cellExistsByColumnAndRow($col, $row)) ? $worksheet->getCellByColumnAndRow($col, $row)->getValue() : $default_val; } - public function formatData($data, $template, $table_name) { + public function formatData($data, $template, $table_name) + { $columns = $template[$table_name]; $header = array_shift($data); // 第一行是表头 $diff = array_diff(array_column($columns, 'name'), $header); if ($diff) { - throw new \Exception(sprintf(t('error_header_need_columns'), implode(',', $diff))); // excel表缺少字段$diff + throw new \Exception(sprintf(t('error_header_need_columns'), $table_name, implode(',', $diff))); // excel表缺少字段$diff } // 跳过表头和正问之间的描述和demo行 @@ -226,59 +231,34 @@ class ModelToolGdImport extends Model { return $result; } - public function validate($datas, $type) { - foreach ($datas as $index => $data) { - $columns = $this->{'template_' . $type}[$index]; + /** + * @throws Exception + */ + public function validate($datas, $type) + { + foreach ($datas as $table => $data) { + $columns = $this->{'template_' . $type}[$table]; $required_map = array_column($columns, 'require', 'code'); $field_name_map = array_column($columns, 'name', 'code'); foreach ($data as $index => $item) { foreach ($item as $code => $value) { if ($required_map[$code] && empty($value)) { // 如果必填且$value为空 - throw new \Exception(sprintf(t('error_filed_required'), $index, $index + $this->data_start_line, $field_name_map[$code])); // $index为0的数据实际上是excel第3行 + throw new \Exception(sprintf(t('error_filed_required'), $table, $index + $this->data_start_line, $field_name_map[$code])); // $index为0的数据实际上是excel第3行 } } } } } - public function validateServiceLogic($data) { - foreach ($data as $index => $item) { - if (!$this->isTrackingCode($item['platform'],$item['tracking_code'])) { - throw new \Exception(sprintf($this->language->get('error_tracking_code'), $index + $this->data_start_line , $item['tracking_code'])); - } - $query = $this->db->query("SELECT order_id FROM `" . DB_PREFIX . "order` WHERE order_id = '" . $item['order_id'] . "'"); - if (!$query->num_rows) { - throw new \Exception(sprintf($this->language->get('error_order_id'), $index + $this->data_start_line , $item['order_id'])); - } else { - if (!in_array(\Services\StateMachine::SHIPPED, array_keys(\Services\StateMachine::getInstance($item['order_id'])->nextBackendStatuses()))) { - throw new \Exception(sprintf($this->language->get('error_order_status'), $index + $this->data_start_line , $item['order_id'])); - } - } - // 验证某个订单的某个快递单号数据是否已经存在 - foreach ($data as $index => $item) { - $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_shippingtrack` WHERE order_id = '" . $item['order_id'] . "' AND tracking_number = '" . $item['tracking_number'] . "' AND tracking_code = '" . $item['tracking_code'] . "'"); - if ($query->num_rows) { - throw new \Exception(sprintf(t('error_tracking_number_exist'), $index + $this->data_start_line)); - } - } - } - // 验证Excel中快递单号是否重复 - $data_all = array_map(function ($item){ - return $item['order_id'] . '||' . $item['tracking_number'] . '||' . $item['tracking_code']; - }, $data); - $values_count = array_count_values($data_all); - foreach ($values_count as $key => $value) { - if ($value > 1) { - $ott_arr = explode('||', $key); - throw new \Exception(sprintf(t('error_tracking_number_repeate'), $ott_arr[0], $ott_arr[1], $ott_arr[2])); - } - } + public function validateServiceLogic($data) + { } - function download($type) { + function download($type) + { // set appropriate timeout limit - set_time_limit( 0 ); + set_time_limit(0); ini_set('memory_limit', '512M'); // create a new workbook @@ -298,9 +278,9 @@ class ModelToolGdImport extends Model { $workbook->setActiveSheetIndex($i++); $worksheet = $workbook->getActiveSheet(); $worksheet->setTitle($table); -// $func = $this->convertUnderline('get_' . $key); - $this->populateWorksheet($worksheet, [], $columns, $table, $type); - $worksheet->freezePaneByColumnAndRow( 1, 2 ); + $func = $this->convertUnderline('get_' . $table); + $this->populateWorksheet($worksheet, $this->{$func}(), $columns, $table, $type); + $worksheet->freezePaneByColumnAndRow(1, 2); } $workbook->setActiveSheetIndex(0); @@ -309,7 +289,7 @@ class ModelToolGdImport extends Model { //header('Content-Type: application/vnd.ms-excel'); //header('Content-Disposition: attachment;filename="GDExportImport_products_'.$datetime.'.xls"'); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); - header('Content-Disposition: attachment;filename="GDExportImport_'.$type.'_'.$datetime.'.xlsx"'); + header('Content-Disposition: attachment;filename="GDExportImport_' . $type . '_' . $datetime . '.xlsx"'); header('Cache-Control: max-age=0'); // If you're serving to IE over SSL, then the following may be needed @@ -319,17 +299,18 @@ class ModelToolGdImport extends Model { header('Pragma: public'); // HTTP/1.0 //$writer = PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xls'); - $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx'); - if(ob_get_length()){ + $writer = IOFactory::createWriter($workbook, 'Xlsx'); + if (ob_get_length()) { ob_clean(); } $writer->save('php://output'); } + /** * @param $worksheet - * @param $data 要写入工作表的数据, 每个记录中的字段顺序必须和$template一致 - * @param $template 工作表的表头,如:array(array('key'=>'product_id','name'=>'Product ID','format'=>'box'),array('key'=>'model','name'=>'Model ','format'=>'box')),其中value的实际长度即为excel列的宽度,需要宽一点的直接加空格 + * @param $data , 要写入工作表的数据, 每个记录中的字段顺序必须和$template一致 + * @param $template , 工作表的表头,如:array(array('key'=>'product_id','name'=>'Product ID','format'=>'box'),array('key'=>'model','name'=>'Model ','format'=>'box')),其中value的实际长度即为excel列的宽度,需要宽一点的直接加空格 */ private function populateWorksheet(&$worksheet, $data, $columns, $tableName) { @@ -360,7 +341,7 @@ class ModelToolGdImport extends Model { foreach ($columns as $item) { $cell_value = $row[$item['code']]; if ($item['type'] == 'html') { - $cell_value = html_entity_decode($cell_value,ENT_QUOTES,'UTF-8'); + $cell_value = html_entity_decode($cell_value, ENT_QUOTES, 'UTF-8'); } $this->setCell($worksheet, $i, $j++, $cell_value, $this->format[$item['format']]); } @@ -368,12 +349,14 @@ class ModelToolGdImport extends Model { } } - private function setCell(&$worksheet, $row/*1-based*/, $col/*0-based*/, $val, $style=NULL) { + private function setCell(&$worksheet, $row/*1-based*/, $col/*0-based*/, $val, $style = NULL) + { $sel_index = $this->IntToChr($col) . $row; $worksheet->setCellValueExplicit($sel_index, $val, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); } - private function IntToChr($index) { + private function IntToChr($index) + { $index--; $str = ''; if (floor($index / 26) > 0) { @@ -382,12 +365,16 @@ class ModelToolGdImport extends Model { return $str . chr($index % 26 + 65); } - public function upload($file_path) { + /** + * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception + */ + public function upload($file_path) + { $this->load->language('tool/gd_import'); // parse uploaded spreadsheet file - $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($file_path); - $objReader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); + $inputFileType = IOFactory::identify($file_path); + $objReader = IOFactory::createReader($inputFileType); $objReader->setReadDataOnly(true); $reader = $objReader->load($file_path); @@ -399,10 +386,10 @@ class ModelToolGdImport extends Model { $i++; } $this->validate($data, $type); - //$this->validateServiceLogic($data); + $this->validateServiceLogic($data); $data = $this->refactorData($data); $data = $this->perfectData($data, $type); - dd($data); + // dd($data); $this->cache->set('gd_import' . $this->user->getId(), $data); return count($data); @@ -413,7 +400,8 @@ class ModelToolGdImport extends Model { * @param $data * @return array|mixed */ - public function refactorData($data) { + public function refactorData($data) + { $result = array_shift($data); $array_keys = array_keys(current($result)); $primary_id_name = array_shift($array_keys); @@ -435,17 +423,18 @@ class ModelToolGdImport extends Model { * @param $data * @return array|mixed */ - public function perfectData($data, $type) { + public function perfectData($data, $type) + { $result = []; switch ($type) { case 'product': foreach ($data as $item) { $item['date_added'] = date($this->language->get('datetime_format')); - $item['date_added'] = date($this->language->get('datetime_format')); - if ($item['categorys']) { + $item['date_modified'] = date($this->language->get('datetime_format')); + if ($item['categories']) { $item['product_category'] = array_map(function ($item) { return trim($item); - }, explode(',', $item['categorys'])); + }, explode(',', $item['categories'])); } if ($item['filters']) { $item['product_filter'] = array_map(function ($item) { @@ -459,22 +448,23 @@ class ModelToolGdImport extends Model { case 'category': foreach ($data as $item) { $item['date_added'] = date($this->language->get('datetime_format')); - $item['date_added'] = date($this->language->get('datetime_format')); + $item['date_modified'] = date($this->language->get('datetime_format')); } break; case 'option': - brake; + break; case 'attribute': - brake; + break; case 'manufacturer': - brake; + break; case 'customer_groups': break; } return $result; } - public function import($index) { + public function import($index) + { $type = 'product'; $data = $this->cache->get('gd_import' . $this->user->getId()); if ($index >= count($data)) { @@ -518,7 +508,8 @@ class ModelToolGdImport extends Model { * @param $index // 从0开始,0为第一个sheet * @throws Exception */ - private function getSheet($reader, $type, $table_index, $index, $transpose = false) { + private function getSheet($reader, $type, $table_index, $index, $transpose = false) + { if ($reader->getSheetCount() <= $index) { throw new \Exception($this->language->get('error_sheet_not_exist')); } @@ -552,15 +543,24 @@ class ModelToolGdImport extends Model { return $result; } - private function utf8($data) { + private function convertUnderline($str) + { + $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) { + return strtoupper($matches[2]); + }, $str); + return $str; + } + + private function utf8($data) + { if (is_array($data)) { foreach ($data as $item) { $this->utf8($item); } } else { - $encode = mb_detect_encoding($data, array("GB2312","GBK","BIG5","ASCII","UTF-8")); - if( $encode != "UTF-8") { + $encode = mb_detect_encoding($data, array("GB2312", "GBK", "BIG5", "ASCII", "UTF-8")); + if ($encode != "UTF-8") { $data = mb_convert_encoding($data, 'UTF-8', $encode); } } -- Gitee From 07bc0fa8d4bca44a260c26e1a8bcd55fd69b3283 Mon Sep 17 00:00:00 2001 From: TL Date: Thu, 10 Feb 2022 18:33:18 +0800 Subject: [PATCH 03/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=EF=BC=8C=E6=8F=8F=E8=BF=B0=E8=A1=A8=E8=B7=9F?= =?UTF-8?q?=E4=B8=BB=E8=A1=A8=E5=90=88=E5=B9=B6=EF=BC=8C=E7=94=A8=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E5=AD=97=E6=AE=B5=E6=9D=A5=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/controller/tool/gd_import.php | 4 +- upload/admin/model/tool/gd_import.php | 98 +++++++++++++++++++++- 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php index fc445cbc..aa78d204 100644 --- a/upload/admin/controller/tool/gd_import.php +++ b/upload/admin/controller/tool/gd_import.php @@ -35,7 +35,6 @@ class ControllerToolGdImport extends Controller $this->load->model('tool/gd_import'); $result = $this->model_tool_gd_import->upload($file); } catch (\Exception $e) { - throw $e; $json['error'] = $e->getMessage(); } @@ -43,7 +42,8 @@ class ControllerToolGdImport extends Controller $json['count'] = $result; } } - $this->response->renderJson($json); + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput($json); } public function import() { diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index aaa7034e..e1c87174 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -95,7 +95,7 @@ class ModelToolGdImport extends Model protected $template_product = array( 'product' => array( array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'categorys', 'name' => 'Categories', 'cell_width' => 8, 'require' => false,), + array('code' => 'categories', 'name' => 'Categories', 'cell_width' => 8, 'require' => false,), array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false,), array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false,), array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false,), @@ -194,6 +194,36 @@ class ModelToolGdImport extends Model ), ); private $data_start_line = 3; // 正式数据从第几行开始 + private $languages = [ + 1 =>'zh_cn', + 2 => 'en_gb' + ]; + + public function __construct($registry) + { + parent::__construct($registry); + + foreach (['product', "category"] as $type) { + foreach ($this->{'template_' . $type} as $table => $columns) { + if ($table == $type) { + foreach ($this->{'template_' . $type}[$type . '_description'] as $column) { + foreach ($this->languages as $language_code) { + if (in_array($column['code'], [$type . '_id', 'language_id'])) { + continue; + } + $new_column = $column; + $new_column['code'] .= '_' . $language_code; + $new_column['name'] .= '_' . $language_code; + $columns[] = $new_column; + } + } + } + $this->{'template_' . $type}[$table] = $columns; + unset($this->{'template_' . $type}[$type . '_description']); + + } + } + } public function getCell(&$worksheet, $row, $col, $default_val = '') { @@ -255,6 +285,10 @@ class ModelToolGdImport extends Model { } + /** + * @throws \PhpOffice\PhpSpreadsheet\Exception + * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception + */ function download($type) { // set appropriate timeout limit @@ -272,6 +306,19 @@ class ModelToolGdImport extends Model // creating the worksheet $i = 0; foreach ($this->{'template_' . $type} as $table => $columns) { + // if ($table == $type) { + // foreach ($this->{'template_' . $type}[$type . '_description'] as $column) { + // foreach ($this->languages as $language_code) { + // $new_column = $column; + // $new_column['code'] .= '_' . $language_code; + // $new_column['name'] .= '_' . $language_code; + // $columns[] = $new_column; + // } + // } + // } + // if ($table == $type . '_description') { + // continue; + // } if ($i > 0) { $workbook->createSheet(); } @@ -402,10 +449,23 @@ class ModelToolGdImport extends Model */ public function refactorData($data) { + $type = 'product'; $result = array_shift($data); $array_keys = array_keys(current($result)); $primary_id_name = array_shift($array_keys); $result = array_column($result, null, $primary_id_name); + + foreach ($result as $i => $item) { + foreach ($item as $field => $value) { + $lang_code = substr($field, -5); + if (in_array($lang_code, $this->languages)) { + $language_id = array_flip($this->languages)[$lang_code]; + $result[$i][$type . '_description'][$language_id][substr($field, 0, -6)] = $value; + unset($result[$i][$field]); + } + } + } + foreach ($data as $table => $items) { foreach ($items as $item) { if (isset($item['language_id'])) { @@ -543,6 +603,42 @@ class ModelToolGdImport extends Model return $result; } + private function getProduct() { + return []; + } + + private function getProductDescription() { + return []; + } + + private function getProductImage() { + return []; + } + + private function getProductOption() { + return []; + } + + private function getProductAttribute() { + return []; + } + + private function getProductSpecial() { + return []; + } + + private function getProductDiscount() { + return []; + } + + private function getProductReward() { + return []; + } + + private function getProductRelated() { + return []; + } + private function convertUnderline($str) { $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) { -- Gitee From 1d86c75dd04e9b55c6f976e1886343de842abaa5 Mon Sep 17 00:00:00 2001 From: TL Date: Fri, 11 Feb 2022 11:27:40 +0800 Subject: [PATCH 04/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/controller/tool/gd_import.php | 7 +- upload/admin/model/tool/gd_import.php | 144 ++++++++++++++------- 2 files changed, 103 insertions(+), 48 deletions(-) diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php index aa78d204..768546bf 100644 --- a/upload/admin/controller/tool/gd_import.php +++ b/upload/admin/controller/tool/gd_import.php @@ -43,7 +43,7 @@ class ControllerToolGdImport extends Controller } } $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput($json); + $this->response->setOutput(json_encode($json)); } public function import() { @@ -51,12 +51,13 @@ class ControllerToolGdImport extends Controller $json = []; try { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->import($this->request->get['index']); + $this->model_tool_gd_import->import('product', 1); } catch (\Exception $e) { $json['error'] = $e->getMessage(); } - $this->jsonOutput($json); + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($json)); } public function download() { diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index e1c87174..2e550c59 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -13,7 +13,7 @@ class ModelToolGdImport extends Model { /** * 格式要求: - * 1、每个模板的第一个sheet必须为主表,其他sheet为附表 + * 1、每个模板的第一个sheet必须为主表,第二个sheet为主表对应的描述表,其他sheet为附表,key必须为不含前缀的表名 * 2、每个sheet的第一个字段必须主键(主表)或外键(附表) * 3、每个字段的code必须与数据库字段名称一致 * 4、每个sheet的key必须与创建方法中使用的key一致 @@ -43,54 +43,88 @@ class ModelToolGdImport extends Model array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), ), ); - protected $template_base = array( - 'filter_groups' => array( + protected $template_filter_group = array( + 'filter_group' => array( + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'filter_group_description' => array( array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), - 'filters' => array( + ); + protected $template_filter = array( + 'filter' => array( array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true,), array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'filter_description' => array( + array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + ), + ); + protected $template_manufacturer = array( + ); + protected $template_option = array( + 'option' => array( + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true,), array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), - 'options' => array( + 'option_description' => array( array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), - 'option_values' => array( + 'option_value' => array( array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true,), array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false,), array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false,), array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), - 'customer_groups' => array( + 'option_value_description' => array( + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), + array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false,), + ), + ); + protected $template_customer_group = array( + 'customer_group' => array( + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'approval', 'name' => 'Approval', 'cell_width' => 8, 'require' => true,), + ), + 'customer_group_description' => array( array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), array('code' => 'description', 'name' => 'Description', 'cell_width' => 28,'require' => false,) ), - 'attribute_groups' => array( + ); + protected $template_attribute_group = array( + 'attribute_group' => array( + array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'attribute_group_description' => array( array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), - 'attributes' => array( + ); + protected $template_attribute = array( + 'attribute' => array( array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + ), + 'attribute_description' => array( + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ) + ), ); protected $template_product = array( 'product' => array( @@ -198,6 +232,7 @@ class ModelToolGdImport extends Model 1 =>'zh_cn', 2 => 'en_gb' ]; + private $count_one_time = 10; // 一次请求处理的商品数量 public function __construct($registry) { @@ -439,13 +474,13 @@ class ModelToolGdImport extends Model // dd($data); $this->cache->set('gd_import' . $this->user->getId(), $data); - return count($data); + return ceil(count($data) / $this->count_one_time); } /** * 将数据重组为调用model层原生方法所需的结构 * @param $data - * @return array|mixed + * @return array */ public function refactorData($data) { @@ -481,7 +516,8 @@ class ModelToolGdImport extends Model /** * 将数据补充其他必要数据,比如date_added,date_modify等调用创建函数必须要,但是excel导入没有提供的字段。使数据达到可以调用model层创建方法的标准 * @param $data - * @return array|mixed + * @param $type + * @return array */ public function perfectData($data, $type) { @@ -492,14 +528,20 @@ class ModelToolGdImport extends Model $item['date_added'] = date($this->language->get('datetime_format')); $item['date_modified'] = date($this->language->get('datetime_format')); if ($item['categories']) { - $item['product_category'] = array_map(function ($item) { - return trim($item); - }, explode(',', $item['categories'])); + $categories = explode(',', $item['categories']); + if ($categories) { + $item['product_category'] = array_map(function ($item) { + return trim($item); + }, $categories); + } } if ($item['filters']) { - $item['product_filter'] = array_map(function ($item) { - return trim($item); - }, explode(',', $item['filters'])); + $filters = explode(',', $item['filters']); + if ($filters) { + $item['product_filter'] = array_map(function ($item) { + return trim($item); + }, $filters); + } } $result[] = $item; @@ -509,64 +551,76 @@ class ModelToolGdImport extends Model foreach ($data as $item) { $item['date_added'] = date($this->language->get('datetime_format')); $item['date_modified'] = date($this->language->get('datetime_format')); + if ($item['filters']) { + $filters = explode(',', $item['filters']); + if ($filters) { + $item['category_filter'] = array_map(function ($item) { + return trim($item); + }, $filters); + } + } } break; + // case 'filter_group': + // case 'filter': case 'option': - break; + case 'customer_group': + case 'attribute_group': case 'attribute': - break; case 'manufacturer': break; - case 'customer_groups': - break; } return $result; } - public function import($index) + public function import($type, $page) { - $type = 'product'; $data = $this->cache->get('gd_import' . $this->user->getId()); - if ($index >= count($data)) { - throw new \Exception('data not exist!'); - } + $data = array_slice($data, $this->count_one_time * ($page - 1), $this->count_one_time, true); + + $ids = array_column($data, $type . '_id'); + $ids_exist = table($type)->whereIn($type . '_id', $ids)->pluck($type . '_id')->toArray(); + switch ($type) { case 'product': $this->load->model('catalog/product'); foreach ($data as $item) { - if (is_numeric($item['product_id'])) { + if (!is_numeric($item['product_id']) || !in_array($item['product_id'], $ids_exist)) { $this->model_catalog_product->addProduct($item); } else { - $this->model_catalog_product->updateProduct($item['product_id'], $item); + $this->model_catalog_product->editProduct($item['product_id'], $item); } } break; case 'category': $this->load->model('catalog/category'); foreach ($data as $item) { - if (is_numeric($item['category_id'])) { + if (!is_numeric($item['category_id']) || !in_array($item['category_id'], $ids_exist)) { $this->model_catalog_category->addCategory($item); } else { - $this->model_catalog_product->updateCategory($item['product_id'], $item); + $this->model_catalog_category->editCategory($item['product_id'], $item); } } break; + // case 'filter_group': + // case 'filter': case 'option': - brake; + case 'customer_group': + case 'attribute_group': case 'attribute': - brake; case 'manufacturer': - brake; - case 'customer_groups': break; } - $this->createData($data[$index]); } /** * @param $reader + * @param $type + * @param $table_index * @param $index // 从0开始,0为第一个sheet - * @throws Exception + * @param bool $transpose + * @return array + * @throws \PhpOffice\PhpSpreadsheet\Exception */ private function getSheet($reader, $type, $table_index, $index, $transpose = false) { -- Gitee From faa94a6cf9f791258a21c65ccc7f226d538de7b7 Mon Sep 17 00:00:00 2001 From: TL Date: Fri, 11 Feb 2022 15:48:38 +0800 Subject: [PATCH 05/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA-=E6=8F=8F=E8=BF=B0=E8=A1=A8=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=B0=E4=B8=BB=E8=A1=A8=E9=80=9A=E8=BF=87=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E5=AD=97=E6=AE=B5=E5=8C=BA=E5=88=86=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/controller/tool/gd_import.php | 8 +- .../admin/language/zh-cn/tool/gd_import.php | 10 +- upload/admin/model/tool/gd_import.php | 419 +++++++++--------- .../admin/view/template/tool/gd_import.twig | 31 +- 4 files changed, 250 insertions(+), 218 deletions(-) diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php index 768546bf..8833f4c2 100644 --- a/upload/admin/controller/tool/gd_import.php +++ b/upload/admin/controller/tool/gd_import.php @@ -33,7 +33,7 @@ class ControllerToolGdImport extends Controller try { $this->load->model('tool/gd_import'); - $result = $this->model_tool_gd_import->upload($file); + $result = $this->model_tool_gd_import->upload($file, $this->request->post['type']); } catch (\Exception $e) { $json['error'] = $e->getMessage(); } @@ -51,7 +51,7 @@ class ControllerToolGdImport extends Controller $json = []; try { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->import('product', 1); + $this->model_tool_gd_import->import($this->request->get['type'], $this->request->get['page']); } catch (\Exception $e) { $json['error'] = $e->getMessage(); } @@ -62,7 +62,7 @@ class ControllerToolGdImport extends Controller public function download() { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->download('product'); + $this->model_tool_gd_import->download($this->request->post['type']); } @@ -152,6 +152,8 @@ class ControllerToolGdImport extends Controller 'href' => $this->url->link('tool/gd_import', 'user_token=' . $this->session->data['user_token']) ); + $data['types'] = ['product', "category", "option", "customer_group", "attribute_group", "attribute"]; + $data['action'] = $this->url->link('tool/gd_import/upload', 'user_token=' . $this->session->data['user_token']); $data['download_href'] = $this->url->link('tool/gd_import/download', 'user_token=' . $this->session->data['user_token']); diff --git a/upload/admin/language/zh-cn/tool/gd_import.php b/upload/admin/language/zh-cn/tool/gd_import.php index 66e14b89..adaf6807 100644 --- a/upload/admin/language/zh-cn/tool/gd_import.php +++ b/upload/admin/language/zh-cn/tool/gd_import.php @@ -13,13 +13,19 @@ $_['heading_title'] = '商品导入导出'; // Text $_['text_success'] = '成功:您已成功导入您的数据'; $_['text_upload_confirm'] = '确认开始导入?'; +$_['text_product'] = '商品'; +$_['text_category'] = '分类'; +$_['text_option'] = '选项'; +$_['text_customer_group'] = '客户组'; +$_['text_attribute'] = '属性'; +$_['text_attribute_group'] = '属性组'; // Entry -$_['entry_download'] = '商品导出'; +$_['entry_download'] = '导出'; $_['entry_file'] = '导入文件'; // Button labels -$_['button_download'] = '导出商品'; +$_['button_download'] = '导出'; $_['button_import'] = '导入'; $_['help_template'] = '请输入要导出的商品范围,然后点击导出商品按钮'; diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index 2e550c59..5b1c6667 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -22,211 +22,176 @@ class ModelToolGdImport extends Model */ protected $template_category = array( 'category' => array( - array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false,), - array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false,), - array('code' => 'top', 'name' => 'Top', 'cell_width' => 8, 'require' => false,), - array('code' => 'column', 'name' => 'Column', 'cell_width' => 8, 'require' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), - array('code' => 'image', 'name' => 'images', 'cell_width' => 28,'require' => false,), - array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false,), - array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false,), - array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false,) - ), - 'category_description' => array( - array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false,), - array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true,), - array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false,), - array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), + array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'top', 'name' => 'Top', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'column', 'name' => 'Column', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'image', 'name' => 'images', 'cell_width' => 28,'require' => false, 'multi_language' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false, 'multi_language' => true,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true, 'multi_language' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false, 'multi_language' => true,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false, 'multi_language' => true,), ), ); protected $template_filter_group = array( 'filter_group' => array( - array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'filter_group_description' => array( - array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), ), ); protected $template_filter = array( 'filter' => array( - array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'filter_description' => array( - array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), ), ); protected $template_manufacturer = array( ); protected $template_option = array( 'option' => array( - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'option_description' => array( - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), ), 'option_value' => array( - array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'option_value_description' => array( - array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false,), + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false, 'multi_language' => true,), ), ); protected $template_customer_group = array( 'customer_group' => array( - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'approval', 'name' => 'Approval', 'cell_width' => 8, 'require' => true,), - ), - 'customer_group_description' => array( - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 28,'require' => false,) + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'approval', 'name' => 'Approval', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 28,'require' => false, 'multi_language' => true,), ), ); protected $template_attribute_group = array( 'attribute_group' => array( - array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'attribute_group_description' => array( - array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), ), ); protected $template_attribute = array( 'attribute' => array( - array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) - ), - 'attribute_description' => array( - array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), ), ); protected $template_product = array( 'product' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'categories', 'name' => 'Categories', 'cell_width' => 8, 'require' => false,), - array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false,), - array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false,), - array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false,), - array('code' => 'upc', 'name' => 'UPC', 'cell_width' => 8, 'require' => false,), - array('code' => 'ean', 'name' => 'EAN', 'cell_width' => 8, 'require' => false,), - array('code' => 'jan', 'name' => 'JAN', 'cell_width' => 8, 'require' => false,), - array('code' => 'isbn', 'name' => 'ISBN', 'cell_width' => 8, 'require' => false,), - array('code' => 'mpn', 'name' => 'MPN', 'cell_width' => 8, 'require' => false,), - array('code' => 'location', 'name' => 'Location', 'cell_width' => 8, 'require' => false,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), - array('code' => 'model', 'name' => 'Model', 'cell_width' => 8, 'require' => true,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false,), - array('code' => 'shipping', 'name' => 'Require Shipping','cell_width' => 8, 'require' => true,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => true,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), - array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false,), - array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false,), - array('code' => 'date_available', 'name' => 'Date Available', 'cell_width' => 18,'require' => false,), - array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false,), - array('code' => 'weight_class_id', 'name' => 'Weight Unit', 'cell_width' => 8, 'require' => false,), - array('code' => 'length', 'name' => 'Length', 'cell_width' => 8, 'require' => false,), - array('code' => 'width', 'name' => 'Width', 'cell_width' => 8, 'require' => false,), - array('code' => 'height', 'name' => 'Height', 'cell_width' => 8, 'require' => false,), - array('code' => 'length_class_id', 'name' => 'Length Unit', 'cell_width' => 8, 'require' => false,), - array('code' => 'tax_class_id', 'name' => 'Tax Class ID', 'cell_width' => 8, 'require' => false,), - array('code' => 'viewed', 'name' => 'Viewed', 'cell_width' => 8, 'require' => false,), - array('code' => 'stock_status_id', 'name' => 'Stock Status ID', 'cell_width' => 8, 'require' => false,), - array('code' => 'relateds', 'name' => 'Related IDs', 'cell_width' => 8, 'require' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,), - array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false,), - array('code' => 'minimum', 'name' => 'Minimum', 'cell_width' => 8, 'require' => false,), - array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false,) - ), - 'product_description' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false,), - array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true,), - array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false,), - array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false,), - array('code' => 'tag', 'name' => 'Tags', 'cell_width' => 28,'require' => false,) + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'categories', 'name' => 'Categories', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'upc', 'name' => 'UPC', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'ean', 'name' => 'EAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'jan', 'name' => 'JAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'isbn', 'name' => 'ISBN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'mpn', 'name' => 'MPN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'location', 'name' => 'Location', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'model', 'name' => 'Model', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false, 'multi_language' => false,), + array('code' => 'shipping', 'name' => 'Require Shipping','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'date_available', 'name' => 'Date Available', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'weight_class_id', 'name' => 'Weight Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'length', 'name' => 'Length', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'width', 'name' => 'Width', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'height', 'name' => 'Height', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'length_class_id', 'name' => 'Length Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'tax_class_id', 'name' => 'Tax Class ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'viewed', 'name' => 'Viewed', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'stock_status_id', 'name' => 'Stock Status ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'relateds', 'name' => 'Related IDs', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'minimum', 'name' => 'Minimum', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false, 'multi_language' => true,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true, 'multi_language' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false, 'multi_language' => true,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false, 'multi_language' => true,), + array('code' => 'tag', 'name' => 'Tags', 'cell_width' => 28,'require' => false, 'multi_language' => true,), ), 'product_image' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => true,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => true, 'multi_language' => false,), array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), 'product_option' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => false,), - array('code' => 'value', 'name' => 'Value', 'cell_width' => 18,'require' => false,), - array('code' => 'required', 'name' => 'Required', 'cell_width' => 18,'require' => false,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), - array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), - array('code' => 'price_prefix', 'name' => 'Price Prefix', 'cell_width' => 8, 'require' => false,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), - array('code' => 'points_prefix', 'name' => 'Points Prefix', 'cell_width' => 8, 'require' => false,), - array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'value', 'name' => 'Value', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'required', 'name' => 'Required', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price_prefix', 'name' => 'Price Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'points_prefix', 'name' => 'Points Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), array('code' => 'weight_prefix', 'name' => 'Weight Prefix', 'cell_width' => 8, 'require' => false,) ), 'product_attribute' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'text', 'name' => 'Text', 'cell_width' => 18,'require' => true,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'text', 'name' => 'Text', 'cell_width' => 18,'require' => true, 'multi_language' => false,), ), 'product_special' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), - array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false,), - array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false, 'multi_language' => false,), ), 'product_discount' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false,), - array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false,), - array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false,), - array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false, 'multi_language' => false,), ), 'product_reward' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), ), 'product_related' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true,), - array('code' => 'related_id', 'name' => 'Related Product ID','cell_width' => 8, 'require' => true,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'related_id', 'name' => 'Related Product ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), ), ); + public $types = ['product', "category", "option", "customer_group", "attribute_group", "attribute"]; private $data_start_line = 3; // 正式数据从第几行开始 private $languages = [ 1 =>'zh_cn', @@ -238,24 +203,20 @@ class ModelToolGdImport extends Model { parent::__construct($registry); - foreach (['product', "category"] as $type) { - foreach ($this->{'template_' . $type} as $table => $columns) { - if ($table == $type) { - foreach ($this->{'template_' . $type}[$type . '_description'] as $column) { - foreach ($this->languages as $language_code) { - if (in_array($column['code'], [$type . '_id', 'language_id'])) { - continue; - } - $new_column = $column; - $new_column['code'] .= '_' . $language_code; - $new_column['name'] .= '_' . $language_code; - $columns[] = $new_column; - } + foreach ($this->types as $type) { + foreach ($this->{'template_' . $type} as &$columns) { + foreach ($columns as $field => $column) { + if (!$column['multi_language']) { + continue; + } + foreach ($this->languages as $language_code) { + $new_column = $column; + $new_column['code'] .= '_' . $language_code; + $new_column['name'] .= '_' . $language_code; + $columns[] = $new_column; } + unset($columns[$field]); } - $this->{'template_' . $type}[$table] = $columns; - unset($this->{'template_' . $type}[$type . '_description']); - } } } @@ -341,19 +302,6 @@ class ModelToolGdImport extends Model // creating the worksheet $i = 0; foreach ($this->{'template_' . $type} as $table => $columns) { - // if ($table == $type) { - // foreach ($this->{'template_' . $type}[$type . '_description'] as $column) { - // foreach ($this->languages as $language_code) { - // $new_column = $column; - // $new_column['code'] .= '_' . $language_code; - // $new_column['name'] .= '_' . $language_code; - // $columns[] = $new_column; - // } - // } - // } - // if ($table == $type . '_description') { - // continue; - // } if ($i > 0) { $workbook->createSheet(); } @@ -361,7 +309,7 @@ class ModelToolGdImport extends Model $worksheet = $workbook->getActiveSheet(); $worksheet->setTitle($table); $func = $this->convertUnderline('get_' . $table); - $this->populateWorksheet($worksheet, $this->{$func}(), $columns, $table, $type); + $this->populateWorksheet($worksheet, $this->{$func}(), $columns, $table); $worksheet->freezePaneByColumnAndRow(1, 2); } @@ -450,7 +398,7 @@ class ModelToolGdImport extends Model /** * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ - public function upload($file_path) + public function upload($file_path, $type) { $this->load->language('tool/gd_import'); @@ -460,7 +408,6 @@ class ModelToolGdImport extends Model $objReader->setReadDataOnly(true); $reader = $objReader->load($file_path); - $type = 'product'; $data = []; $i = 0; foreach ($this->{'template_' . $type} as $index => $item) { @@ -484,23 +431,25 @@ class ModelToolGdImport extends Model */ public function refactorData($data) { - $type = 'product'; + foreach ($data as $table => &$items) { + foreach ($items as $i => $item) { + foreach ($item as $field => $value) { + $lang_code = substr($field, -5); + if (in_array($lang_code, $this->languages)) { + $language_id = array_flip($this->languages)[$lang_code]; + $items[$i][$table . '_description'][$language_id][substr($field, 0, -6)] = $value; + unset($items[$i][$field]); + } + } + } + } + $result = array_shift($data); $array_keys = array_keys(current($result)); $primary_id_name = array_shift($array_keys); $result = array_column($result, null, $primary_id_name); - foreach ($result as $i => $item) { - foreach ($item as $field => $value) { - $lang_code = substr($field, -5); - if (in_array($lang_code, $this->languages)) { - $language_id = array_flip($this->languages)[$lang_code]; - $result[$i][$type . '_description'][$language_id][substr($field, 0, -6)] = $value; - unset($result[$i][$field]); - } - } - } - + unset($items); foreach ($data as $table => $items) { foreach ($items as $item) { if (isset($item['language_id'])) { @@ -563,12 +512,14 @@ class ModelToolGdImport extends Model break; // case 'filter_group': // case 'filter': - case 'option': case 'customer_group': + case 'option': case 'attribute_group': case 'attribute': - case 'manufacturer': + $result = $data; break; + // case 'manufacturer': + // break; } return $result; } @@ -605,11 +556,47 @@ class ModelToolGdImport extends Model // case 'filter_group': // case 'filter': case 'option': + $this->load->model('catalog/option'); + foreach ($data as $item) { + if (!is_numeric($item['option_id']) || !in_array($item['option_id'], $ids_exist)) { + $this->model_catalog_option->addOption($item); + } else { + $this->model_catalog_option->editOption($item['product_id'], $item); + } + } + break; case 'customer_group': + $this->load->model('customer/customer_group'); + foreach ($data as $item) { + if (!is_numeric($item['customer_group_id']) || !in_array($item['customer_group_id'], $ids_exist)) { + $this->model_customer_customer_group->addCustomerGroup($item); + } else { + $this->model_customer_customer_group->editCustomerGroup($item['product_id'], $item); + } + } + break; case 'attribute_group': + $this->load->model('catalog/attribute_group'); + foreach ($data as $item) { + if (!is_numeric($item['attribute_group_id']) || !in_array($item['attribute_group_id'], $ids_exist)) { + $this->model_catalog_attribute_group->addAttributeGroup($item); + } else { + $this->model_catalog_attribute_group->editAttributeGroup($item['product_id'], $item); + } + } + break; case 'attribute': - case 'manufacturer': + $this->load->model('catalog/attribute'); + foreach ($data as $item) { + if (!is_numeric($item['attribute_id']) || !in_array($item['attribute_id'], $ids_exist)) { + $this->model_catalog_attribute->addAttribute($item); + } else { + $this->model_catalog_attribute->editAttribute($item['product_id'], $item); + } + } break; + // case 'manufacturer': + // break; } } @@ -661,10 +648,6 @@ class ModelToolGdImport extends Model return []; } - private function getProductDescription() { - return []; - } - private function getProductImage() { return []; } @@ -693,6 +676,30 @@ class ModelToolGdImport extends Model return []; } + private function getCategory() { + return []; + } + + private function getOption() { + return []; + } + + private function getOptionValue() { + return []; + } + + private function getCustomerGroup() { + return []; + } + + private function getAttributeGroup() { + return []; + } + + private function getAttribute() { + return []; + } + private function convertUnderline($str) { $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) { diff --git a/upload/admin/view/template/tool/gd_import.twig b/upload/admin/view/template/tool/gd_import.twig index d16fbdbf..d89cda1d 100644 --- a/upload/admin/view/template/tool/gd_import.twig +++ b/upload/admin/view/template/tool/gd_import.twig @@ -25,20 +25,35 @@

{{ heading_title }}

-
+
-
- {{ button_download }} +
+
+ + + + +
{{ help_template }}
+ +
-
- +
-
+
+
{{ help_file }}
@@ -83,6 +98,7 @@ $('#button-import').on('click', function() { layer.closeAll(); var formData = new FormData(); formData.append('csvfile', file); + formData.append('type', $('#input-import-type').val()); $.ajax({ url: 'index.php?route=tool/gd_import/upload&user_token={{ user_token }}', @@ -112,8 +128,9 @@ $('#button-import').on('click', function() { }); function job() { + $type = $('#input-import-type').val(); $.ajax({ - url: 'index.php?route=tool/gd_import/import&user_token={{ user_token }}&index=' + index, + url: 'index.php?route=tool/gd_import/import&user_token={{ user_token }}&index=' + index + '&type=' + $type, type: 'get', contentType: false, dataType: 'json', -- Gitee From 0ff1ddcdb9f922fe8adb01acfc30d9e9fbcbcbd9 Mon Sep 17 00:00:00 2001 From: TL Date: Mon, 14 Feb 2022 16:40:28 +0800 Subject: [PATCH 06/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/controller/tool/gd_import.php | 4 +- upload/admin/model/tool/gd_import.php | 491 ++++++++++++++------- 2 files changed, 330 insertions(+), 165 deletions(-) diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php index 8833f4c2..e5d9a6be 100644 --- a/upload/admin/controller/tool/gd_import.php +++ b/upload/admin/controller/tool/gd_import.php @@ -51,7 +51,7 @@ class ControllerToolGdImport extends Controller $json = []; try { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->import($this->request->get['type'], $this->request->get['page']); + $this->model_tool_gd_import->import($this->request->get['type'], $this->request->get['index'] + 1); } catch (\Exception $e) { $json['error'] = $e->getMessage(); } @@ -62,7 +62,7 @@ class ControllerToolGdImport extends Controller public function download() { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->download($this->request->post['type']); + $this->model_tool_gd_import->download($this->request->post['type'], 0, 111); } diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index 5b1c6667..5d6384df 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -22,182 +22,180 @@ class ModelToolGdImport extends Model */ protected $template_category = array( 'category' => array( - array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'top', 'name' => 'Top', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'column', 'name' => 'Column', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'image', 'name' => 'images', 'cell_width' => 28,'require' => false, 'multi_language' => false,), - array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false, 'multi_language' => true,), - array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true, 'multi_language' => true,), - array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false, 'multi_language' => true,), - array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false, 'multi_language' => true,), + array('code' => 'category_id', 'name' => 'Category ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'parent_id', 'name' => 'Parent ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'top', 'name' => 'Top', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'column', 'name' => 'Column', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'image', 'name' => 'images', 'cell_width' => 28, 'require' => false, 'multi_language' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38, 'require' => false, 'multi_language' => true,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18, 'require' => true, 'multi_language' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description', 'cell_width' => 18, 'require' => false, 'multi_language' => true,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18, 'require' => false, 'multi_language' => true,), ), ); protected $template_filter_group = array( 'filter_group' => array( - array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), ), ); protected $template_filter = array( 'filter' => array( - array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'filter_id', 'name' => 'Filter ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'filter_group_id', 'name' => 'Filter Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), ), ); - protected $template_manufacturer = array( - ); + protected $template_manufacturer = array(); protected $template_option = array( 'option' => array( - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'type', 'name' => 'Type', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), ), 'option_value' => array( - array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Value', 'cell_width' => 28,'require' => false, 'multi_language' => true,), + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Value', 'cell_width' => 28, 'require' => false, 'multi_language' => true,), ), ); protected $template_customer_group = array( 'customer_group' => array( - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'approval', 'name' => 'Approval', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 28,'require' => false, 'multi_language' => true,), + array('code' => 'customer_group_id', 'name' => 'Customer Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'approval', 'name' => 'Approval', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 28, 'require' => false, 'multi_language' => true,), ), ); protected $template_attribute_group = array( 'attribute_group' => array( - array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'attribute_group_id', 'name' => 'Attribute Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), ), ); protected $template_attribute = array( 'attribute' => array( - array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'attribute_group_id','name' => 'Attribute Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'attribute_group_id', 'name' => 'Attribute Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), ), ); protected $template_product = array( 'product' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'categories', 'name' => 'Categories', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'upc', 'name' => 'UPC', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'ean', 'name' => 'EAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'jan', 'name' => 'JAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'isbn', 'name' => 'ISBN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'mpn', 'name' => 'MPN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'location', 'name' => 'Location', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'model', 'name' => 'Model', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => false, 'multi_language' => false,), - array('code' => 'shipping', 'name' => 'Require Shipping','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'date_available', 'name' => 'Date Available', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'weight_class_id', 'name' => 'Weight Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'length', 'name' => 'Length', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'width', 'name' => 'Width', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'height', 'name' => 'Height', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'length_class_id', 'name' => 'Length Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'tax_class_id', 'name' => 'Tax Class ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'viewed', 'name' => 'Viewed', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'stock_status_id', 'name' => 'Stock Status ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'relateds', 'name' => 'Related IDs', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'minimum', 'name' => 'Minimum', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'name', 'name' => 'Name', 'cell_width' => 28,'require' => true, 'multi_language' => true,), - array('code' => 'description', 'name' => 'Description', 'cell_width' => 38,'require' => false, 'multi_language' => true,), - array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18,'require' => true, 'multi_language' => true,), - array('code' => 'meta_description', 'name' => 'Meta Description','cell_width' => 18,'require' => false, 'multi_language' => true,), - array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18,'require' => false, 'multi_language' => true,), - array('code' => 'tag', 'name' => 'Tags', 'cell_width' => 28,'require' => false, 'multi_language' => true,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'categories', 'name' => 'Categories', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'manufacturer_id', 'name' => 'Manufacturer ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'filters', 'name' => 'Filters', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sku', 'name' => 'SKU', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'upc', 'name' => 'UPC', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'ean', 'name' => 'EAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'jan', 'name' => 'JAN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'isbn', 'name' => 'ISBN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'mpn', 'name' => 'MPN', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'location', 'name' => 'Location', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'model', 'name' => 'Model', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28, 'require' => false, 'multi_language' => false,), + array('code' => 'shipping', 'name' => 'Require Shipping', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_added', 'name' => 'Date Added', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'date_modified', 'name' => 'Date Modified', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'date_available', 'name' => 'Date Available', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'weight_class_id', 'name' => 'Weight Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'length', 'name' => 'Length', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'width', 'name' => 'Width', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'height', 'name' => 'Height', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'length_class_id', 'name' => 'Length Unit', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'tax_class_id', 'name' => 'Tax Class ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'viewed', 'name' => 'Viewed', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'stock_status_id', 'name' => 'Stock Status ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'relateds', 'name' => 'Related IDs', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'minimum', 'name' => 'Minimum', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'status', 'name' => 'Status', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'name', 'name' => 'Name', 'cell_width' => 28, 'require' => true, 'multi_language' => true,), + array('code' => 'description', 'name' => 'Description', 'cell_width' => 38, 'require' => false, 'multi_language' => true,), + array('code' => 'meta_title', 'name' => 'Meta Title', 'cell_width' => 18, 'require' => true, 'multi_language' => true,), + array('code' => 'meta_description', 'name' => 'Meta Description', 'cell_width' => 18, 'require' => false, 'multi_language' => true,), + array('code' => 'meta_keyword', 'name' => 'Meta Keyword', 'cell_width' => 18, 'require' => false, 'multi_language' => true,), + array('code' => 'tag', 'name' => 'Tags', 'cell_width' => 28, 'require' => false, 'multi_language' => true,), ), 'product_image' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'image', 'name' => 'Image', 'cell_width' => 28,'require' => true, 'multi_language' => false,), - array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'image', 'name' => 'Image', 'cell_width' => 28, 'require' => true, 'multi_language' => false,), + array('code' => 'sort_order', 'name' => 'Sort Order', 'cell_width' => 8, 'require' => false,) ), 'product_option' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'value', 'name' => 'Value', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'required', 'name' => 'Required', 'cell_width' => 18,'require' => false, 'multi_language' => false,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'price_prefix', 'name' => 'Price Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'points_prefix', 'name' => 'Points Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'weight_prefix', 'name' => 'Weight Prefix', 'cell_width' => 8, 'require' => false,) + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_id', 'name' => 'Option ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'option_value_id', 'name' => 'Option Value ID', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'value', 'name' => 'Value', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'required', 'name' => 'Required', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'subtract', 'name' => 'Subtract', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price_prefix', 'name' => 'Price Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'points_prefix', 'name' => 'Points Prefix', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'weight', 'name' => 'Weight', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'weight_prefix', 'name' => 'Weight Prefix', 'cell_width' => 8, 'require' => false,) ), 'product_attribute' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'text', 'name' => 'Text', 'cell_width' => 18,'require' => true, 'multi_language' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'attribute_id', 'name' => 'Attribute ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'language_id', 'name' => 'Language ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'text', 'name' => 'Text', 'cell_width' => 18, 'require' => true, 'multi_language' => false,), ), 'product_special' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id', 'name' => 'Customer Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), ), 'product_discount' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18,'require' => false, 'multi_language' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id', 'name' => 'Customer Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'quantity', 'name' => 'Quantity', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'priority', 'name' => 'Priority', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'price', 'name' => 'Price', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_start', 'name' => 'Date Start', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), + array('code' => 'date_end', 'name' => 'Date End', 'cell_width' => 18, 'require' => false, 'multi_language' => false,), ), 'product_reward' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'customer_group_id','name' => 'Customer Group ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), - ), - 'product_related' => array( - array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), - array('code' => 'related_id', 'name' => 'Related Product ID','cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'product_id', 'name' => 'Product ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'customer_group_id', 'name' => 'Customer Group ID', 'cell_width' => 8, 'require' => true, 'multi_language' => false,), + array('code' => 'points', 'name' => 'Points', 'cell_width' => 8, 'require' => false, 'multi_language' => false,), ), ); public $types = ['product', "category", "option", "customer_group", "attribute_group", "attribute"]; private $data_start_line = 3; // 正式数据从第几行开始 private $languages = [ - 1 =>'zh_cn', - 2 => 'en_gb' + 1 => 'en_gb', + 2 => 'zh_cn', ]; private $count_one_time = 10; // 一次请求处理的商品数量 + private $min_product_id = 0; + private $max_product_id = 0; + private $exportway = 'pid'; public function __construct($registry) { @@ -269,7 +267,7 @@ class ModelToolGdImport extends Model foreach ($data as $index => $item) { foreach ($item as $code => $value) { - if ($required_map[$code] && empty($value)) { // 如果必填且$value为空 + if ($required_map[$code] && $value === '') { // 如果必填且$value为空 throw new \Exception(sprintf(t('error_filed_required'), $table, $index + $this->data_start_line, $field_name_map[$code])); // $index为0的数据实际上是excel第3行 } } @@ -285,12 +283,17 @@ class ModelToolGdImport extends Model * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ - function download($type) + function download($type, $pid_from = 0, $pid_to = 0) { // set appropriate timeout limit set_time_limit(0); ini_set('memory_limit', '512M'); + if ($type == 'product') { + $this->min_product_id = $pid_from; + $this->max_product_id = $pid_to; + } + // create a new workbook $workbook = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); @@ -484,6 +487,14 @@ class ModelToolGdImport extends Model }, $categories); } } + if ($item['relateds']) { + $relateds = explode(',', $item['relateds']); + if ($relateds) { + $item['product_related'] = array_map(function ($item) { + return trim($item); + }, $relateds); + } + } if ($item['filters']) { $filters = explode(',', $item['filters']); if ($filters) { @@ -508,6 +519,7 @@ class ModelToolGdImport extends Model }, $filters); } } + $result[] = $item; } break; // case 'filter_group': @@ -527,7 +539,7 @@ class ModelToolGdImport extends Model public function import($type, $page) { $data = $this->cache->get('gd_import' . $this->user->getId()); - $data = array_slice($data, $this->count_one_time * ($page - 1), $this->count_one_time, true); + $data = array_slice($data, $this->count_one_time * ($page - 1), $this->count_one_time, true); $ids = array_column($data, $type . '_id'); $ids_exist = table($type)->whereIn($type . '_id', $ids)->pluck($type . '_id')->toArray(); @@ -549,7 +561,7 @@ class ModelToolGdImport extends Model if (!is_numeric($item['category_id']) || !in_array($item['category_id'], $ids_exist)) { $this->model_catalog_category->addCategory($item); } else { - $this->model_catalog_category->editCategory($item['product_id'], $item); + $this->model_catalog_category->editCategory($item['category_id'], $item); } } break; @@ -561,7 +573,7 @@ class ModelToolGdImport extends Model if (!is_numeric($item['option_id']) || !in_array($item['option_id'], $ids_exist)) { $this->model_catalog_option->addOption($item); } else { - $this->model_catalog_option->editOption($item['product_id'], $item); + $this->model_catalog_option->editOption($item['option_id'], $item); } } break; @@ -571,7 +583,7 @@ class ModelToolGdImport extends Model if (!is_numeric($item['customer_group_id']) || !in_array($item['customer_group_id'], $ids_exist)) { $this->model_customer_customer_group->addCustomerGroup($item); } else { - $this->model_customer_customer_group->editCustomerGroup($item['product_id'], $item); + $this->model_customer_customer_group->editCustomerGroup($item['customer_group_id'], $item); } } break; @@ -581,7 +593,7 @@ class ModelToolGdImport extends Model if (!is_numeric($item['attribute_group_id']) || !in_array($item['attribute_group_id'], $ids_exist)) { $this->model_catalog_attribute_group->addAttributeGroup($item); } else { - $this->model_catalog_attribute_group->editAttributeGroup($item['product_id'], $item); + $this->model_catalog_attribute_group->editAttributeGroup($item['attribute_group_id'], $item); } } break; @@ -591,7 +603,7 @@ class ModelToolGdImport extends Model if (!is_numeric($item['attribute_id']) || !in_array($item['attribute_id'], $ids_exist)) { $this->model_catalog_attribute->addAttribute($item); } else { - $this->model_catalog_attribute->editAttribute($item['product_id'], $item); + $this->model_catalog_attribute->editAttribute($item['attribute_id'], $item); } } break; @@ -644,60 +656,213 @@ class ModelToolGdImport extends Model return $result; } - private function getProduct() { - return []; + private function getProduct() + { + $query = "SELECT DISTINCT "; + $query .= " p.*,"; + $query .= " GROUP_CONCAT( DISTINCT CAST(pc.category_id AS CHAR(11)) SEPARATOR \",\" ) AS categories,"; + $query .= " wc.unit AS weight_unit,"; + $query .= " mc.unit AS length_unit, "; + $query .= " GROUP_CONCAT( DISTINCT CAST(pr.related_id AS CHAR(11)) SEPARATOR \",\" ) AS relateds "; + $query .= "FROM `" . DB_PREFIX . "product` p "; + $query .= "LEFT JOIN `" . DB_PREFIX . "product_to_category` pc ON p.product_id=pc.product_id "; + $query .= "LEFT JOIN `" . DB_PREFIX . "weight_class_description` wc ON wc.weight_class_id = p.weight_class_id "; + $query .= "LEFT JOIN `" . DB_PREFIX . "length_class_description` mc ON mc.length_class_id=p.length_class_id "; + $query .= "LEFT JOIN `" . DB_PREFIX . "product_related` pr ON pr.product_id=p.product_id "; + $query .= "WHERE 1=1 "; + if ($this->exportway == 'pid') { + $query .= "AND p.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + } + $query .= "GROUP BY p.product_id "; + $query .= "ORDER BY p.product_id, pc.category_id "; + if ($this->exportway == 'page') { + $query .= "LIMIT " . ($this->page - 1) * $this->count_prepage . ", " . $this->count_prepage . ";"; + } + $result = $this->db->query($query); + + if ($this->exportway == 'page' && $result->rows) { + $this->min_product_id = $result->rows[0]['product_id']; + $this->max_product_id = $result->rows[count($result->rows) - 1]['product_id']; + } + + return $this->flattenDescriptions($result->rows, $this->getProductDescription()); } - private function getProductImage() { - return []; + private function getProductDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_description` pd "; + $query .= "WHERE pd.language_id in (" . implode(',', array_keys($this->languages)) . ") AND pd.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pd.`product_id`, pd.`language_id`;"; + $result = $this->db->query($query); + return $result->rows; } - private function getProductOption() { - return []; + private function getProductImage() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_image` pi "; + $query .= "WHERE pi.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pi.`product_id`, pi.`sort_order`, pi.`image`;"; + $result = $this->db->query($query); + + return $result->rows; } - private function getProductAttribute() { - return []; + private function getProductOption() + { + $query = "SELECT po.*, pov.* "; + $query .= "FROM `" . DB_PREFIX . "product_option` po "; + $query .= "LEFT JOIN `" . DB_PREFIX . "product_option_value` pov ON pov.product_option_id = po.product_option_id "; + $query .= "WHERE po.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY po.product_id, po.option_id, pov.option_value_id;"; + + $result = $this->db->query($query); + return $result->rows; } - private function getProductSpecial() { - return []; + private function getProductAttribute() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_attribute` pa "; + $query .= "WHERE pa.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pa.`product_id`, pa.`attribute_id`, pa.`language_id`;"; + $result = $this->db->query($query); + return $result->rows; } - private function getProductDiscount() { - return []; + private function getProductSpecial() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_special` pa "; + $query .= "WHERE pa.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pa.`product_id`;"; + $result = $this->db->query($query); + return $result->rows; } - private function getProductReward() { - return []; + private function getProductDiscount() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_discount` pa "; + $query .= "WHERE pa.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pa.`product_id`;"; + $result = $this->db->query($query); + return $result->rows; } - private function getProductRelated() { - return []; + private function getProductReward() + { + $query = "SELECT * FROM `" . DB_PREFIX . "product_reward` pa "; + $query .= "WHERE pa.product_id BETWEEN " . $this->min_product_id . " AND " . $this->max_product_id . " "; + $query .= "ORDER BY pa.`product_id`;"; + $result = $this->db->query($query); + return $result->rows; } - private function getCategory() { - return []; + private function getCategory() + { + $query = "SELECT DISTINCT c.* FROM `" . DB_PREFIX . "category` c "; + $query .= "ORDER BY c.`parent_id`, `sort_order`, c.`category_id`;"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getCategoryDescription()); } - private function getOption() { - return []; + private function getCategoryDescription() + { + $query = "SELECT DISTINCT * FROM `" . DB_PREFIX . "category_description` WHERE language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; } - private function getOptionValue() { - return []; + private function getOption() + { + $query = "SELECT * FROM `" . DB_PREFIX . "option` o ORDER BY o.option_id;"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getOptionDescription()); } - private function getCustomerGroup() { - return []; + private function getOptionDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "option_description` WHERE language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; } - private function getAttributeGroup() { - return []; + private function getOptionValue() + { + $query = "SELECT * FROM `" . DB_PREFIX . "option_value`"; + $query .= "ORDER BY option_id, option_value_id;"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getOptionValueDescription()); } - private function getAttribute() { - return []; + private function getOptionValueDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "option_value_description` ovd WHERE ovd.language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; + } + + private function getCustomerGroup() + { + $query = "SELECT * FROM `" . DB_PREFIX . "customer_group` ORDER BY customer_group_id"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getCustomerGroupDescription()); + } + + private function getCustomerGroupDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "customer_group_description` WHERE language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; + } + + private function getAttributeGroup() + { + $query = "SELECT * FROM `" . DB_PREFIX . "attribute_group` ORDER BY attribute_group_id"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getAttributeGroupDescription()); + } + + private function getAttributeGroupDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "attribute_group_description` WHERE language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; + } + + private function getAttribute() + { + $query = "SELECT * FROM `" . DB_PREFIX . "attribute` "; + $query .= "ORDER BY attribute_id"; + $result = $this->db->query($query); + return $this->flattenDescriptions($result->rows, $this->getAttributeDescription()); + } + + private function getAttributeDescription() + { + $query = "SELECT * FROM `" . DB_PREFIX . "attribute_description`WHERE language_id in (" . implode(',', array_keys($this->languages)) . ") "; + $result = $this->db->query($query); + return $result->rows; + } + + /** + * @param $items , 该参数第一列必须为主键 + * @param $descriptions + * @return array + */ + private function flattenDescriptions($items, $descriptions): array + { + $idField = array_keys($items[0])[0] ?? 0; + $items = array_column($items, null, $idField); + + foreach ($descriptions as $description) { + $id = $description[$idField]; + $langCode = $this->languages[$description['language_id']]; + unset($description['language_id']); + unset($description[$idField]); + foreach ($description as $key => $value) { + $items[$id][$key . '_' . $langCode] = $value; + } + } + + return $items; } private function convertUnderline($str) -- Gitee From b7933428817b88c82b4e84f09eb03d558e64d926 Mon Sep 17 00:00:00 2001 From: TL Date: Mon, 14 Feb 2022 17:36:57 +0800 Subject: [PATCH 07/18] =?UTF-8?q?=E5=95=86=E5=93=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload/admin/controller/tool/gd_import.php | 2 +- .../admin/language/zh-cn/tool/gd_import.php | 7 + upload/admin/model/tool/gd_import.php | 19 ++- .../admin/view/template/tool/gd_import.twig | 143 +++++++++++++----- 4 files changed, 133 insertions(+), 38 deletions(-) diff --git a/upload/admin/controller/tool/gd_import.php b/upload/admin/controller/tool/gd_import.php index e5d9a6be..508a590f 100644 --- a/upload/admin/controller/tool/gd_import.php +++ b/upload/admin/controller/tool/gd_import.php @@ -62,7 +62,7 @@ class ControllerToolGdImport extends Controller public function download() { $this->load->model('tool/gd_import'); - $this->model_tool_gd_import->download($this->request->post['type'], 0, 111); + $this->model_tool_gd_import->download($this->request->post['type'], $this->request->post); } diff --git a/upload/admin/language/zh-cn/tool/gd_import.php b/upload/admin/language/zh-cn/tool/gd_import.php index adaf6807..1b10409d 100644 --- a/upload/admin/language/zh-cn/tool/gd_import.php +++ b/upload/admin/language/zh-cn/tool/gd_import.php @@ -19,10 +19,17 @@ $_['text_option'] = '选项'; $_['text_customer_group'] = '客户组'; $_['text_attribute'] = '属性'; $_['text_attribute_group'] = '属性组'; +$_['text_export_pid'] = '按商品 ID 导出'; +$_['text_export_page'] = '分批导出'; // Entry $_['entry_download'] = '导出'; $_['entry_file'] = '导入文件'; +$_['entry_exportway_sel'] = '商品导出方式:'; +$_['entry_start_id'] = '商品 ID (从):'; +$_['entry_end_id'] = '商品 ID (到):'; +$_['entry_number'] = '导出数量:'; +$_['entry_index'] = '导出批次:'; // Button labels $_['button_download'] = '导出'; diff --git a/upload/admin/model/tool/gd_import.php b/upload/admin/model/tool/gd_import.php index 5d6384df..77bc1406 100644 --- a/upload/admin/model/tool/gd_import.php +++ b/upload/admin/model/tool/gd_import.php @@ -196,6 +196,8 @@ class ModelToolGdImport extends Model private $min_product_id = 0; private $max_product_id = 0; private $exportway = 'pid'; + private $count_prepage; + private $page; public function __construct($registry) { @@ -283,15 +285,26 @@ class ModelToolGdImport extends Model * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ - function download($type, $pid_from = 0, $pid_to = 0) + function download($type, $post = []) { // set appropriate timeout limit set_time_limit(0); ini_set('memory_limit', '512M'); if ($type == 'product') { - $this->min_product_id = $pid_from; - $this->max_product_id = $pid_to; + if (isset($post['exportway'])) { + if ($post['exportway'] == 'pid') { + $this->min_product_id = $post['min']; + $this->max_product_id = $post['max']; + $this->exportway = $post['exportway']; + } else if ($post['exportway'] == 'page') { + $this->count_prepage = $post['min']; + $this->page = $post['max']; + $this->exportway = $post['exportway']; + } else { + echo "exportway error!"; + } + } } // create a new workbook diff --git a/upload/admin/view/template/tool/gd_import.twig b/upload/admin/view/template/tool/gd_import.twig index d89cda1d..2aa82543 100644 --- a/upload/admin/view/template/tool/gd_import.twig +++ b/upload/admin/view/template/tool/gd_import.twig @@ -25,47 +25,94 @@

{{ heading_title }}

- -
- -
-
- + {% for export_type in types %} + + {% endfor %} + + + + +
+
{{ help_template }}
+
+
+ + +
+
+ +
+
+
+
+ +
+ - - - + +
{{ help_file }}
-
{{ help_template }}
-
- -
- -
-
- -
- - -
{{ help_file }}
-
-
-
-
- +
+
+ +
+
- +