├── tests ├── Controller │ ├── Jobs │ │ ├── Xml │ │ │ └── Import │ │ │ │ ├── _testfiles │ │ │ │ └── .gitkeep │ │ │ │ └── StandardTest.php │ │ ├── Stock │ │ │ └── Import │ │ │ │ └── Csv │ │ │ │ ├── _testfiles │ │ │ │ ├── stock_1.csv │ │ │ │ └── stock_2.csv │ │ │ │ └── StandardTest.php │ │ ├── Order │ │ │ ├── Status │ │ │ │ └── Csv │ │ │ │ │ ├── _test │ │ │ │ │ └── status.csv │ │ │ │ │ └── StandardTest.php │ │ │ └── Cleanup │ │ │ │ ├── Unpaid │ │ │ │ └── StandardTest.php │ │ │ │ └── Unfinished │ │ │ │ └── StandardTest.php │ │ ├── Customer │ │ │ └── Import │ │ │ │ ├── Csv │ │ │ │ └── _testfiles │ │ │ │ │ ├── empty.csv │ │ │ │ │ ├── position │ │ │ │ │ └── customers.csv │ │ │ │ │ └── valid │ │ │ │ │ └── customers.csv │ │ │ │ └── Xml │ │ │ │ └── StandardTest.php │ │ ├── Product │ │ │ ├── Import │ │ │ │ ├── Csv │ │ │ │ │ └── _testfiles │ │ │ │ │ │ ├── empty.csv │ │ │ │ │ │ ├── position │ │ │ │ │ │ └── products.csv │ │ │ │ │ │ └── valid │ │ │ │ │ │ └── products.csv │ │ │ │ └── Xml │ │ │ │ │ └── _testfiles │ │ │ │ │ ├── product_1.xml │ │ │ │ │ └── product_2.xml │ │ │ ├── Bought │ │ │ │ └── StandardTest.php │ │ │ └── Export │ │ │ │ ├── StandardTest.php │ │ │ │ └── Sitemap │ │ │ │ └── StandardTest.php │ │ ├── Supplier │ │ │ └── Import │ │ │ │ ├── Csv │ │ │ │ └── _testfiles │ │ │ │ │ ├── empty.csv │ │ │ │ │ ├── position │ │ │ │ │ └── suppliers.csv │ │ │ │ │ ├── import.zip │ │ │ │ │ └── valid │ │ │ │ │ └── suppliers.csv │ │ │ │ └── Xml │ │ │ │ ├── StandardTest.php │ │ │ │ └── _testfiles │ │ │ │ ├── supplier_1.xml │ │ │ │ └── supplier_2.xml │ │ ├── Catalog │ │ │ ├── Import │ │ │ │ ├── Csv │ │ │ │ │ └── _testfiles │ │ │ │ │ │ ├── empty.csv │ │ │ │ │ │ ├── position │ │ │ │ │ │ └── catalog.csv │ │ │ │ │ │ ├── invalid │ │ │ │ │ │ └── catalog.csv │ │ │ │ │ │ └── valid │ │ │ │ │ │ └── catalog.csv │ │ │ │ └── Xml │ │ │ │ │ ├── _testfiles │ │ │ │ │ ├── catalog_2.xml │ │ │ │ │ └── catalog_1.xml │ │ │ │ │ └── StandardTest.php │ │ │ └── Export │ │ │ │ └── Sitemap │ │ │ │ └── StandardTest.php │ │ ├── Group │ │ │ └── Import │ │ │ │ └── Xml │ │ │ │ ├── _testfiles │ │ │ │ ├── group_1.xml │ │ │ │ └── group_2.xml │ │ │ │ └── StandardTest.php │ │ ├── Common │ │ │ ├── Product │ │ │ │ └── Import │ │ │ │ │ └── Csv │ │ │ │ │ ├── Processor │ │ │ │ │ └── DoneTest.php │ │ │ │ │ └── Cache │ │ │ │ │ ├── Product │ │ │ │ │ └── StandardTest.php │ │ │ │ │ ├── Catalog │ │ │ │ │ └── StandardTest.php │ │ │ │ │ ├── Supplier │ │ │ │ │ └── StandardTest.php │ │ │ │ │ └── Attribute │ │ │ │ │ └── StandardTest.php │ │ │ ├── Decorator │ │ │ │ └── BaseTest.php │ │ │ ├── Import │ │ │ │ └── Xml │ │ │ │ │ └── Processor │ │ │ │ │ ├── Lists │ │ │ │ │ └── StandardTest.php │ │ │ │ │ └── Group │ │ │ │ │ └── StandardTest.php │ │ │ ├── Catalog │ │ │ │ └── Import │ │ │ │ │ └── Csv │ │ │ │ │ └── BaseTest.php │ │ │ ├── Supplier │ │ │ │ └── Import │ │ │ │ │ └── Csv │ │ │ │ │ └── BaseTest.php │ │ │ └── Customer │ │ │ │ └── Import │ │ │ │ └── Xml │ │ │ │ └── Processor │ │ │ │ └── Group │ │ │ │ └── StandardTest.php │ │ ├── Basket │ │ │ └── Cleanup │ │ │ │ └── StandardTest.php │ │ ├── Admin │ │ │ ├── Cache │ │ │ │ └── StandardTest.php │ │ │ └── Log │ │ │ │ └── StandardTest.php │ │ ├── BaseTest.php │ │ ├── Index │ │ │ ├── Optimize │ │ │ │ └── StandardTest.php │ │ │ └── Rebuild │ │ │ │ └── StandardTest.php │ │ ├── Attribute │ │ │ └── Import │ │ │ │ └── Xml │ │ │ │ ├── _testfiles │ │ │ │ ├── attribute_1.xml │ │ │ │ └── attribute_2.xml │ │ │ │ └── StandardTest.php │ │ └── Media │ │ │ └── Scale │ │ │ └── StandardTest.php │ └── JobsTest.php ├── config │ ├── resource.php │ └── controller.php ├── phpunit.xml ├── phpunit-coverage.xml └── bootstrap.php ├── i18n ├── ar ├── bg ├── bn ├── ca ├── cs ├── da ├── de ├── el ├── en ├── es ├── et ├── fa ├── fi ├── fr ├── he ├── hr ├── hu ├── id ├── it ├── ja ├── ka ├── ko ├── lb ├── lt ├── lv ├── my ├── nb ├── nl ├── no ├── pl ├── pt ├── ro ├── ru ├── sk ├── sl ├── sr ├── sv ├── th ├── tk ├── tr ├── uk ├── vi ├── zh ├── es_AR ├── pt_BR ├── pt_PT └── zh_CN ├── .gitignore ├── .tx └── config ├── manifest.php ├── src └── Controller │ └── Jobs │ ├── Exception.php │ ├── Iface.php │ ├── Common │ ├── Import │ │ └── Xml │ │ │ ├── Processor │ │ │ ├── Iface.php │ │ │ ├── Base.php │ │ │ ├── Lists │ │ │ │ └── Standard.php │ │ │ ├── Address │ │ │ │ └── Standard.php │ │ │ └── Property │ │ │ │ └── Standard.php │ │ │ └── Traits.php │ ├── Catalog │ │ └── Import │ │ │ └── Csv │ │ │ ├── Cache │ │ │ ├── Base.php │ │ │ └── Iface.php │ │ │ └── Processor │ │ │ ├── Iface.php │ │ │ ├── Done.php │ │ │ └── Base.php │ ├── Product │ │ └── Import │ │ │ └── Csv │ │ │ ├── Cache │ │ │ ├── Base.php │ │ │ ├── Iface.php │ │ │ ├── Product │ │ │ │ └── Standard.php │ │ │ ├── Catalog │ │ │ │ └── Standard.php │ │ │ ├── Supplier │ │ │ │ └── Standard.php │ │ │ └── Attribute │ │ │ │ └── Standard.php │ │ │ └── Processor │ │ │ ├── Iface.php │ │ │ ├── Done.php │ │ │ ├── Property │ │ │ └── Standard.php │ │ │ └── Stock │ │ │ └── Standard.php │ ├── Decorator │ │ ├── Iface.php │ │ └── Base.php │ ├── Supplier │ │ └── Import │ │ │ └── Csv │ │ │ ├── Cache │ │ │ ├── Base.php │ │ │ └── Iface.php │ │ │ └── Processor │ │ │ ├── Iface.php │ │ │ ├── Done.php │ │ │ └── Base.php │ ├── Coupon │ │ └── Import │ │ │ └── Csv │ │ │ └── Processor │ │ │ ├── Iface.php │ │ │ ├── Done.php │ │ │ ├── Code │ │ │ └── Standard.php │ │ │ └── Base.php │ ├── Customer │ │ └── Import │ │ │ ├── Csv │ │ │ └── Processor │ │ │ │ ├── Iface.php │ │ │ │ ├── Done.php │ │ │ │ ├── Address │ │ │ │ └── Standard.php │ │ │ │ └── Property │ │ │ │ └── Standard.php │ │ │ └── Xml │ │ │ └── Processor │ │ │ └── Group │ │ │ └── Standard.php │ ├── Subscription │ │ └── Process │ │ │ └── Processor │ │ │ ├── Iface.php │ │ │ └── Base.php │ └── Types.php │ └── Subscription │ └── Process │ └── Base.php ├── templates └── controller │ └── jobs │ ├── catalog │ └── export │ │ ├── sitemap-index.php │ │ └── sitemap-items.php │ ├── product │ └── export │ │ ├── sitemap-index.php │ │ ├── items-partial-product-standard.php │ │ ├── items-partial-attribute-standard.php │ │ ├── items-partial-text-standard.php │ │ ├── sitemap-items.php │ │ ├── items-body-standard.php │ │ ├── items-partial-price-standard.php │ │ └── items-partial-media-standard.php │ ├── customer │ └── email │ │ └── account │ │ ├── text.php │ │ └── html.mjml │ └── order │ └── email │ └── voucher │ ├── text.php │ └── html.mjml ├── README.md ├── composer.json └── config └── controller.php /tests/Controller/Jobs/Xml/Import/_testfiles/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /i18n/ar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ar -------------------------------------------------------------------------------- /i18n/bg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/bg -------------------------------------------------------------------------------- /i18n/bn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/bn -------------------------------------------------------------------------------- /i18n/ca: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ca -------------------------------------------------------------------------------- /i18n/cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/cs -------------------------------------------------------------------------------- /i18n/da: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/da -------------------------------------------------------------------------------- /i18n/de: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/de -------------------------------------------------------------------------------- /i18n/el: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/el -------------------------------------------------------------------------------- /i18n/en: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/en -------------------------------------------------------------------------------- /i18n/es: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/es -------------------------------------------------------------------------------- /i18n/et: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/et -------------------------------------------------------------------------------- /i18n/fa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/fa -------------------------------------------------------------------------------- /i18n/fi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/fi -------------------------------------------------------------------------------- /i18n/fr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/fr -------------------------------------------------------------------------------- /i18n/he: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/he -------------------------------------------------------------------------------- /i18n/hr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/hr -------------------------------------------------------------------------------- /i18n/hu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/hu -------------------------------------------------------------------------------- /i18n/id: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/id -------------------------------------------------------------------------------- /i18n/it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/it -------------------------------------------------------------------------------- /i18n/ja: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ja -------------------------------------------------------------------------------- /i18n/ka: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ka -------------------------------------------------------------------------------- /i18n/ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ko -------------------------------------------------------------------------------- /i18n/lb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/lb -------------------------------------------------------------------------------- /i18n/lt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/lt -------------------------------------------------------------------------------- /i18n/lv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/lv -------------------------------------------------------------------------------- /i18n/my: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/my -------------------------------------------------------------------------------- /i18n/nb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/nb -------------------------------------------------------------------------------- /i18n/nl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/nl -------------------------------------------------------------------------------- /i18n/no: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/no -------------------------------------------------------------------------------- /i18n/pl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/pl -------------------------------------------------------------------------------- /i18n/pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/pt -------------------------------------------------------------------------------- /i18n/ro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ro -------------------------------------------------------------------------------- /i18n/ru: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/ru -------------------------------------------------------------------------------- /i18n/sk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/sk -------------------------------------------------------------------------------- /i18n/sl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/sl -------------------------------------------------------------------------------- /i18n/sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/sr -------------------------------------------------------------------------------- /i18n/sv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/sv -------------------------------------------------------------------------------- /i18n/th: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/th -------------------------------------------------------------------------------- /i18n/tk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/tk -------------------------------------------------------------------------------- /i18n/tr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/tr -------------------------------------------------------------------------------- /i18n/uk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/uk -------------------------------------------------------------------------------- /i18n/vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/vi -------------------------------------------------------------------------------- /i18n/zh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/zh -------------------------------------------------------------------------------- /i18n/es_AR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/es_AR -------------------------------------------------------------------------------- /i18n/pt_BR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/pt_BR -------------------------------------------------------------------------------- /i18n/pt_PT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/pt_PT -------------------------------------------------------------------------------- /i18n/zh_CN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/i18n/zh_CN -------------------------------------------------------------------------------- /tests/Controller/Jobs/Stock/Import/Csv/_testfiles/stock_1.csv: -------------------------------------------------------------------------------- 1 | U:WH,10,test,2000-01-01T00:00:00 2 | U:CF,,, -------------------------------------------------------------------------------- /tests/Controller/Jobs/Stock/Import/Csv/_testfiles/stock_2.csv: -------------------------------------------------------------------------------- 1 | U:WH,20,test,2000-01-01T00:00:00 2 | U:CF,5,, -------------------------------------------------------------------------------- /tests/Controller/Jobs/Order/Status/Csv/_test/status.csv: -------------------------------------------------------------------------------- 1 | OrderID;OrderProductId;StatusDelivery 2 | 1;;3 3 | 1;2;4 -------------------------------------------------------------------------------- /tests/Controller/Jobs/Customer/Import/Csv/_testfiles/empty.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item type","item status" 2 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Import/Csv/_testfiles/empty.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item type","item status" 2 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Csv/_testfiles/empty.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item type","item status" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tests/tmp 2 | .phpunit.result.cache 3 | .phpunit.cache 4 | .potrans 5 | coveralls.json 6 | coverage.xml 7 | *.log 8 | *.ser 9 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Csv/_testfiles/empty.csv: -------------------------------------------------------------------------------- 1 | "item code","item parent","item label","item status","text type","text content","media url" 2 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Csv/_testfiles/position/suppliers.csv: -------------------------------------------------------------------------------- 1 | supplier.label,supplier.code,supplier.status 2 | supplier1,job_csv_test,1 3 | supplier2,job_csv_test2,1 4 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Csv/_testfiles/import.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aimeos/ai-controller-jobs/HEAD/tests/Controller/Jobs/Supplier/Import/Csv/_testfiles/import.zip -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [o:aimeos:p:aimeos-core:r:controller-jobs] 5 | file_filter = i18n/.po 6 | source_file = i18n/source.pot 7 | source_lang = en 8 | type = PO 9 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Csv/_testfiles/position/catalog.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item parent","item status" 2 | "job csv test product","job_csv_test","",1 3 | "job csv test 2. product","job_csv_test2","job_csv_test",1 4 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Import/Csv/_testfiles/position/products.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item type","item status" 2 | "job csv test product","job_csv_test","default",1 3 | "job csv test 2. product","job_csv_test2","select",1 4 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Customer/Import/Csv/_testfiles/position/customers.csv: -------------------------------------------------------------------------------- 1 | "item label","item code","item status","test property" 2 | "job csv test customer","job@csv.test",1,"testpropval" 3 | "job csv test 2. customer","job2@csv.test",0,"testpropval" 4 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Group/Import/Xml/_testfiles/group_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Group/Import/Xml/_testfiles/group_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Csv/_testfiles/invalid/catalog.csv: -------------------------------------------------------------------------------- 1 | "job_csv_test1","unknown","job csv test category" 2 | "job_csv_test2","","job csv test 2. category","0","unknown","short description" 3 | "job_csv_test3","","job csv test 3. category","0","short","short description","path/to/image.jpg","unknown", 4 | -------------------------------------------------------------------------------- /tests/config/resource.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'from-email' => 'root@localhost', 6 | ], 7 | 'fs' => [ 8 | 'adapter' => 'Standard', 9 | 'basedir' => 'tmp', 10 | ], 11 | 'fs-import' => [ 12 | 'adapter' => 'Standard', 13 | 'basedir' => 'tmp/import', 14 | ], 15 | 'fs-mimeicon' => [ 16 | 'adapter' => 'Standard', 17 | 'basedir' => 'tmp/mime', 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Controller 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Csv/_testfiles/valid/suppliers.csv: -------------------------------------------------------------------------------- 1 | supplier.code,supplier.label,supplier.status,text.languageid,text.type,text.content,media.type,media.url,supplier.address.languageid,supplier.address.countryid,supplier.address.city 2 | job_csv_test,supplier1,1,en,short,nice supplier,default,./images/1.jpg,en,de,Berlin 3 | job_csv_test2,supplier2,1,ru,short,good one,default,./images/1.jpg,ru,ru,Moscow 4 | -------------------------------------------------------------------------------- /manifest.php: -------------------------------------------------------------------------------- 1 | 'ai-controller-jobs', 5 | 'depends' => [ 6 | 'aimeos-core', 7 | ], 8 | 'include' => [ 9 | 'src', 10 | ], 11 | 'i18n' => [ 12 | 'controller/jobs' => 'i18n', 13 | ], 14 | 'config' => [ 15 | 'config', 16 | ], 17 | 'template' => [ 18 | 'controller/jobs/templates' => [ 19 | 'templates/controller/jobs', 20 | ], 21 | ], 22 | 'custom' => [ 23 | 'controller/jobs' => [ 24 | 'src', 25 | ], 26 | ], 27 | ]; 28 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Exception.php: -------------------------------------------------------------------------------- 1 | encoder(); 9 | $baseUrl = $this->get( 'baseUrl' ); 10 | $date = date( 'c' ); 11 | 12 | echo '' . "\n"; 13 | echo '' . "\n"; 14 | 15 | foreach( $this->get( 'siteFiles', [] ) as $name ) { 16 | echo '' . $enc->xml( $baseUrl . $name ) . '' . $date . '' . "\n"; 17 | } 18 | 19 | echo '' . "\n"; -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/sitemap-index.php: -------------------------------------------------------------------------------- 1 | encoder(); 9 | $baseUrl = $this->get( 'baseUrl' ); 10 | $date = date( 'c' ); 11 | 12 | echo '' . "\n"; 13 | echo '' . "\n"; 14 | 15 | foreach( $this->get( 'siteFiles', [] ) as $name ) { 16 | echo '' . $enc->xml( $baseUrl . $name ) . '' . $date . '' . "\n"; 17 | } 18 | 19 | echo '' . "\n"; -------------------------------------------------------------------------------- /tests/phpunit-coverage.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ../src 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Controller/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/config/controller.php: -------------------------------------------------------------------------------- 1 | array( 5 | 'product' => array( 6 | 'export' => array( 7 | 'location' => dirname( __DIR__ ) . DIRECTORY_SEPARATOR . 'tmp', 8 | 'max-items' => 15, 9 | 'max-query' => 5, 10 | 'sitemap' => array( 11 | 'location' => dirname( __DIR__ ) . DIRECTORY_SEPARATOR . 'tmp', 12 | 'max-items' => 15, 13 | 'max-query' => 5, 14 | ), 15 | ), 16 | ), 17 | 'catalog' => array( 18 | 'export' => array( 19 | 'sitemap' => array( 20 | 'location' => dirname( __DIR__ ) . DIRECTORY_SEPARATOR . 'tmp', 21 | 'max-items' => 10, 22 | 'max-query' => 5, 23 | ), 24 | ), 25 | ), 26 | ), 27 | ); 28 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | expectException( \LogicException::class ); 20 | \Aimeos\Controller\Jobs::create( $context, $aimeos, 'unknown' ); 21 | } 22 | 23 | 24 | public function testGet() 25 | { 26 | $context = \TestHelper::context(); 27 | $aimeos = \TestHelper::getAimeos(); 28 | 29 | $list = \Aimeos\Controller\Jobs::get( $context, $aimeos, $aimeos->getCustomPaths( 'controller/jobs' ) ); 30 | 31 | $this->assertGreaterThanOrEqual( 38, count( $list ) ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Iface.php: -------------------------------------------------------------------------------- 1 | 2 | Aimeos logo 3 | 4 | 5 | # Aimeos job controllers 6 | 7 | [![Build Status](https://circleci.com/gh/aimeos/ai-controller-jobs.svg?style=shield)](https://circleci.com/gh/aimeos/ai-controller-jobs) 8 | [![Coverage Status](https://coveralls.io/repos/aimeos/ai-controller-jobs/badge.svg?branch=master)](https://coveralls.io/r/aimeos/ai-controller-jobs?branch=master) 9 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aimeos/ai-controller-jobs/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aimeos/ai-controller-jobs/?branch=master) 10 | [![License](https://poser.pugx.org/aimeos/ai-controller-jobs/license.svg)](https://packagist.org/packages/aimeos/ai-controller-jobs) 11 | 12 | Aimeos job controllers for scheduled tasks in e-commerce projects 13 | 14 | [![Aimeos demo](https://aimeos.org/fileadmin/user_upload/demo.jpg)](http://demo.aimeos.org/) 15 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Processor/Iface.php: -------------------------------------------------------------------------------- 1 | context = $context; 33 | } 34 | 35 | 36 | /** 37 | * Returns the context object 38 | * 39 | * @return \Aimeos\MShop\ContextIface Context object 40 | */ 41 | protected function context() : \Aimeos\MShop\ContextIface 42 | { 43 | return $this->context; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Cache/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 33 | } 34 | 35 | 36 | /** 37 | * Returns the context object 38 | * 39 | * @return \Aimeos\MShop\ContextIface Context object 40 | */ 41 | protected function context() : \Aimeos\MShop\ContextIface 42 | { 43 | return $this->context; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Decorator/Iface.php: -------------------------------------------------------------------------------- 1 | context = $context; 33 | } 34 | 35 | 36 | /** 37 | * Returns the context object 38 | * 39 | * @return \Aimeos\MShop\ContextIface Context object 40 | */ 41 | protected function context() : \Aimeos\MShop\ContextIface 42 | { 43 | return $this->context; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aimeos/ai-controller-jobs", 3 | "description": "Aimeos job controllers for long running tasks", 4 | "keywords": ["aimeos", "extension", "controller", "jobs"], 5 | "homepage": "https://aimeos.org/", 6 | "type": "aimeos-extension", 7 | "license": "LGPL-3.0-or-later", 8 | "support": { 9 | "source": "https://github.com/aimeos/ai-controller-jobs", 10 | "issues": "https://github.com/aimeos/ai-controller-jobs/issues", 11 | "forum": "https://aimeos.org/help", 12 | "wiki": "https://aimeos.org/docs" 13 | }, 14 | "prefer-stable": true, 15 | "minimum-stability": "dev", 16 | "require": { 17 | "php": "^8.0.11", 18 | "aimeos/aimeos-core": "dev-master", 19 | "tecnickcom/tcpdf": "^6.4.1" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "~10.0||~11.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Aimeos\\": "src" 27 | }, 28 | "classmap": [ 29 | "src" 30 | ] 31 | }, 32 | "autoload-dev": { 33 | "psr-4": { 34 | "Aimeos\\": "tests" 35 | }, 36 | "classmap": [ 37 | "tests" 38 | ] 39 | } 40 | } -------------------------------------------------------------------------------- /templates/controller/jobs/customer/email/account/text.php: -------------------------------------------------------------------------------- 1 | 9 | get( 'intro', '' ) ) ) ?> 10 | 11 | 12 | translate( 'controller/jobs', 'An account has been created for you.' ) ) ) ?> 13 | 14 | 15 | translate( 'controller/jobs', 'Your account' ) ) ?> 16 | 17 | translate( 'controller/jobs', 'Account' ) ?>: get( 'account' ) ?> 18 | 19 | translate( 'controller/jobs', 'Password' ) ?>: get( 'password' ) ?: $this->translate( 'controller/jobs', 'Like entered by you' ) ?> 20 | 21 | 22 | translate( 'controller/jobs', 'Login' ) ?>: link( 'client/html/account/index/url', ['locale' => $this->addressItem->getLanguageId()], ['absoluteUri' => 1] ) ?> 23 | 24 | 25 | translate( 'controller/jobs', 'If you have any questions, please reply to this e-mail' ) ) ) ?> 26 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Product/Import/Csv/Processor/DoneTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 23 | $this->object = new \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Done( $this->context, [] ); 24 | } 25 | 26 | 27 | protected function tearDown() : void 28 | { 29 | \Aimeos\MShop::cache( false ); 30 | $this->object = null; 31 | } 32 | 33 | 34 | public function testProcess() 35 | { 36 | $product = \Aimeos\MShop::create( $this->context, 'product' )->create(); 37 | 38 | $result = $this->object->process( $product, array( 'test' ) ); 39 | 40 | $this->assertEquals( array( 'test' ), $result ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Customer/Import/Csv/_testfiles/valid/customers.csv: -------------------------------------------------------------------------------- 1 | code,label,salutation,company,vatid,title,firstname,lastname,address1,address2,address3,postal,city,state,languageid,countryid,telephone,telefax,mobile,email,website,longitude,longitude,birthday,status,groups,address salutation,address company,address vatid,address title,address firstname,address lastname,address address1,address address2,address address3,address postal,address city,address state,address languageid,address countryid,address telephone,address telefax,address mobile,address email,address website,address longitude,address longitude,address birthday,property type,property languageid,property value 2 | job@csv.test,job csv test customer,mrs,Test company,DE12345678,Dr,Susan,Schmidt,test street,1,2. floor,12345,test city,Hamburg,de,DE,4912345678,4987654321,4912345098,job@csv.test,https://aimeos.org,50,10,2000-01-01,1,"admin 3 | editor",mrs,Test company,DE12345678,Dr,Susan,Schmidt,test street,1,2. floor,12345,test city,Hamburg,de,DE,4912345678,4987654321,4912345098,job@csv.test,https://aimeos.org,50,10,2000-01-01,testprop,,test value 4 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Basket/Cleanup/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 22 | 23 | $this->object = new \Aimeos\Controller\Jobs\Basket\Cleanup\Standard( $this->context, $aimeos ); 24 | } 25 | 26 | 27 | protected function tearDown() : void 28 | { 29 | unset( $this->object, $this->context ); 30 | } 31 | 32 | 33 | public function testGetName() 34 | { 35 | $this->assertEquals( 'Cleanup baskets', $this->object->getName() ); 36 | } 37 | 38 | 39 | public function testGetDescription() 40 | { 41 | $this->assertEquals( 'Removes the old baskets from the database', $this->object->getDescription() ); 42 | } 43 | 44 | 45 | public function testRun() 46 | { 47 | $this->object->run(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Admin/Cache/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Admin\Cache\Standard( $context, $aimeos ); 24 | } 25 | 26 | 27 | protected function tearDown() : void 28 | { 29 | $this->object = null; 30 | } 31 | 32 | 33 | public function testGetName() 34 | { 35 | $this->assertEquals( 'Cache cleanup', $this->object->getName() ); 36 | } 37 | 38 | 39 | public function testGetDescription() 40 | { 41 | $text = 'Removes the expired entries from the cache'; 42 | $this->assertEquals( $text, $this->object->getDescription() ); 43 | } 44 | 45 | 46 | public function testRun() 47 | { 48 | $this->object->run(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Processor/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 36 | } 37 | 38 | 39 | /** 40 | * Clean up and store data. 41 | */ 42 | public function finish() 43 | { 44 | $this->saveTypes(); 45 | } 46 | 47 | 48 | /** 49 | * Returns the context item 50 | * 51 | * @return \Aimeos\MShop\ContextIface Context object 52 | */ 53 | protected function context() : \Aimeos\MShop\ContextIface 54 | { 55 | return $this->context; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Cache/Iface.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Cache\Product\Standard( $context ); 23 | } 24 | 25 | 26 | protected function tearDown() : void 27 | { 28 | \Aimeos\MShop::cache( false ); 29 | } 30 | 31 | 32 | public function testGet() 33 | { 34 | $this->assertNotEquals( null, $this->object->get( 'CNC' ) ); 35 | } 36 | 37 | 38 | public function testGetUnknown() 39 | { 40 | $this->assertEquals( null, $this->object->get( 'cache-test' ) ); 41 | } 42 | 43 | 44 | public function testSet() 45 | { 46 | $item = \Aimeos\MShop::create( \TestHelper::context(), 'product' )->create(); 47 | $item->setCode( 'cache-test' ); 48 | $item->setId( 1 ); 49 | 50 | $this->object->set( $item ); 51 | $id = $this->object->get( 'cache-test' ); 52 | 53 | $this->assertEquals( $item->getId(), $id ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Product/Import/Csv/Cache/Catalog/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Cache\Catalog\Standard( $context ); 23 | } 24 | 25 | 26 | protected function tearDown() : void 27 | { 28 | \Aimeos\MShop::cache( false ); 29 | } 30 | 31 | 32 | public function testGet() 33 | { 34 | $this->assertInstanceOf( \Aimeos\MShop\Catalog\Item\Iface::class, $this->object->get( 'root' ) ); 35 | } 36 | 37 | 38 | public function testGetUnknown() 39 | { 40 | $this->assertEquals( null, $this->object->get( 'cache-test' ) ); 41 | } 42 | 43 | 44 | public function testSet() 45 | { 46 | $item = \Aimeos\MShop::create( \TestHelper::context(), 'catalog' )->create(); 47 | $item->setCode( 'cache-test2' ); 48 | $item->setId( 1 ); 49 | 50 | $this->object->set( $item ); 51 | $result = $this->object->get( 'cache-test2' ); 52 | 53 | $this->assertSame( $item, $result ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Product/Import/Csv/Cache/Supplier/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Cache\Supplier\Standard( $context ); 23 | } 24 | 25 | 26 | protected function tearDown() : void 27 | { 28 | \Aimeos\MShop::cache( false ); 29 | } 30 | 31 | 32 | public function testGet() 33 | { 34 | $this->assertInstanceOf( \Aimeos\MShop\Supplier\Item\Iface::class, $this->object->get( 'unitSupplier001' ) ); 35 | } 36 | 37 | 38 | public function testGetUnknown() 39 | { 40 | $this->assertEquals( null, $this->object->get( 'cache-test' ) ); 41 | } 42 | 43 | 44 | public function testSet() 45 | { 46 | $item = \Aimeos\MShop::create( \TestHelper::context(), 'supplier' )->create(); 47 | $item->setCode( 'cache-test2' ); 48 | $item->setId( 1 ); 49 | 50 | $this->object->set( $item ); 51 | $result = $this->object->get( 'cache-test2' ); 52 | 53 | $this->assertSame( $item, $result ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Coupon/Import/Csv/Processor/Iface.php: -------------------------------------------------------------------------------- 1 | stub = $this->getMockBuilder( \Aimeos\Controller\Jobs\Iface::class )->getMock(); 25 | $this->object = new TestBase( $this->stub, $context, $aimeos ); 26 | } 27 | 28 | 29 | protected function tearDown() : void 30 | { 31 | unset( $this->object ); 32 | } 33 | 34 | 35 | public function testGetContext() 36 | { 37 | $this->assertInstanceOf( \Aimeos\MShop\ContextIface::class, $this->object->getContextPublic() ); 38 | } 39 | 40 | 41 | public function testGetAimeos() 42 | { 43 | $this->assertInstanceOf( \Aimeos\Bootstrap::class, $this->object->getAimeosPublic() ); 44 | } 45 | } 46 | 47 | 48 | class TestBase 49 | extends \Aimeos\Controller\Jobs\Common\Decorator\Base 50 | { 51 | public function getContextPublic() 52 | { 53 | return $this->context(); 54 | } 55 | 56 | public function getAimeosPublic() 57 | { 58 | return $this->getAimeos(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Supplier/Import/Csv/Processor/Iface.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 21 | $this->object = new \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Lists\Standard( $this->context ); 22 | } 23 | 24 | 25 | protected function tearDown() : void 26 | { 27 | unset( $this->object, $this->context ); 28 | } 29 | 30 | 31 | public function testProcess() 32 | { 33 | $dom = new \DOMDocument(); 34 | $product = \Aimeos\MShop::create( $this->context, 'product' )->create(); 35 | 36 | $dom->loadXML( ' 37 | 38 | 39 | 40 | 41 | ' ); 42 | 43 | $product = $this->object->process( $product, $dom->firstChild ); 44 | 45 | $this->assertEquals( 1, count( $product->getListItems( 'text' ) ) ); 46 | $this->assertEquals( 1, count( $product->getListItems( 'media' ) ) ); 47 | $this->assertEquals( 1, count( $product->getListItems( 'price' ) ) ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /templates/controller/jobs/order/email/voucher/text.php: -------------------------------------------------------------------------------- 1 | encoder(); 16 | 17 | 18 | $pricetype = 'price:default'; 19 | $pricefmt = $this->translate( 'controller/jobs', $pricetype ); 20 | /// Price format with price value (%1$s) and currency (%2$s) 21 | $priceFormat = $pricefmt !== 'price:default' ? $pricefmt : $this->translate( 'controller/jobs', '%1$s %2$s' ); 22 | 23 | 24 | ?> 25 | get( 'intro', '' ) ) ) ?> 26 | 27 | 28 | translate( 'controller/jobs', 'Your voucher' ) . ': ' . $this->voucher ) ) ?> 29 | 30 | 31 | orderProductItem->getPrice(); $priceCurrency = $this->translate( 'currency', $price->getCurrencyId() ) ?> 32 | number( $price->getValue() + $price->getRebate(), $price->getPrecision() ), $priceCurrency ) ?> 33 | translate( 'controller/jobs', 'The value of your voucher is %1$s', 'The value of your vouchers are %1$s', count( (array) $this->voucher ) ), $value ) ) ) ?> 34 | 35 | 36 | translate( 'controller/jobs', 'You can use your vouchers at any time in our online shop' ) ) ) ?> 37 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Coupon/Import/Csv/Processor/Done.php: -------------------------------------------------------------------------------- 1 | encoder() 22 | 23 | ?> 24 | 25 | listItems as $listItem ) : ?> 26 | getRefItem() ) : ?> 27 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Processor/Iface.php: -------------------------------------------------------------------------------- 1 | encoder() 22 | 23 | ?> 24 | 25 | listItems as $listItem ) : ?> 26 | getRefItem() ) : ?> 27 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/BaseTest.php: -------------------------------------------------------------------------------- 1 | config()->set( 'controller/jobs/to-email', 'me@localhost' ); 28 | 29 | $this->object = new \Aimeos\Controller\Jobs\Example( $context, $aimeos ); 30 | } 31 | 32 | 33 | protected function tearDown() : void 34 | { 35 | unset( $this->object ); 36 | } 37 | 38 | 39 | public function testVal() 40 | { 41 | $method = $this->access( 'val' ); 42 | 43 | $this->assertEquals( 'value', $method->invokeArgs( $this->object, [['key' => ' value '], 'key', 'def'] ) ); 44 | $this->assertEquals( 'def', $method->invokeArgs( $this->object, [['key' => ' '], 'key', 'def'] ) ); 45 | $this->assertEquals( 'def', $method->invokeArgs( $this->object, [[], 'key', 'def'] ) ); 46 | } 47 | 48 | 49 | public function testMail() 50 | { 51 | $result = $this->access( 'mail' )->invokeArgs( $this->object, ['me@localhost', 'test'] ); 52 | $this->assertSame( $this->object, $result ); 53 | } 54 | 55 | 56 | protected function access( $name ) 57 | { 58 | $class = new \ReflectionClass( \Aimeos\Controller\Jobs\Base::class ); 59 | $method = $class->getMethod( $name ); 60 | $method->setAccessible( true ); 61 | 62 | return $method; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Processor/Done.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Index/Optimize/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Index\Optimize\Standard( $context, $aimeos ); 24 | } 25 | 26 | 27 | protected function tearDown() : void 28 | { 29 | $this->object = null; 30 | } 31 | 32 | 33 | public function testGetName() 34 | { 35 | $this->assertEquals( 'Index optimization', $this->object->getName() ); 36 | } 37 | 38 | 39 | public function testGetDescription() 40 | { 41 | $text = 'Optimizes the index for searching products faster'; 42 | $this->assertEquals( $text, $this->object->getDescription() ); 43 | } 44 | 45 | 46 | public function testRun() 47 | { 48 | $context = \TestHelper::context(); 49 | $aimeos = \TestHelper::getAimeos(); 50 | 51 | $indexManagerStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Index\\Manager\\Standard' ) 52 | ->onlyMethods( array( 'optimize' ) ) 53 | ->setConstructorArgs( array( $context ) ) 54 | ->getMock(); 55 | 56 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Index\\Manager\\Standard', $indexManagerStub ); 57 | 58 | $indexManagerStub->expects( $this->once() )->method( 'optimize' ); 59 | 60 | $object = new \Aimeos\Controller\Jobs\Index\Optimize\Standard( $context, $aimeos ); 61 | $object->run(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Attribute/Import/Xml/_testfiles/attribute_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Attribute/Import/Xml/_testfiles/attribute_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Product/Import/Csv/Cache/Attribute/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Cache\Attribute\Standard( $context ); 23 | } 24 | 25 | 26 | protected function tearDown() : void 27 | { 28 | \Aimeos\MShop::cache( false ); 29 | } 30 | 31 | 32 | public function testGet() 33 | { 34 | $item = $this->object->get( 'black', 'color' ); 35 | 36 | $this->assertInstanceOf( '\\Aimeos\\MShop\\Attribute\\Item\\Iface', $item ); 37 | $this->assertEquals( 'black', $item->getCode() ); 38 | $this->assertEquals( 'color', $item->getType() ); 39 | } 40 | 41 | 42 | public function testGetUnknown() 43 | { 44 | $this->assertEquals( null, $this->object->get( 'cache-test', 'color' ) ); 45 | } 46 | 47 | 48 | public function testSet() 49 | { 50 | $item = $this->object->get( 'black', 'color' ); 51 | 52 | $this->assertInstanceOf( '\\Aimeos\\MShop\\Attribute\\Item\\Iface', $item ); 53 | 54 | $item->setCode( 'cache-test' ); 55 | 56 | $this->object->set( $item ); 57 | $item = $this->object->get( 'cache-test', 'color' ); 58 | 59 | $this->assertInstanceOf( '\\Aimeos\\MShop\\Attribute\\Item\\Iface', $item ); 60 | $this->assertEquals( 'cache-test', $item->getCode() ); 61 | $this->assertEquals( 'color', $item->getType() ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Bought/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 25 | $this->aimeos = \TestHelper::getAimeos(); 26 | 27 | $this->object = new \Aimeos\Controller\Jobs\Product\Bought\Standard( $this->context, $this->aimeos ); 28 | } 29 | 30 | 31 | protected function tearDown() : void 32 | { 33 | \Aimeos\MShop::cache( false ); 34 | unset( $this->object ); 35 | } 36 | 37 | 38 | public function testGetName() 39 | { 40 | $this->assertEquals( 'Products bought together', $this->object->getName() ); 41 | } 42 | 43 | 44 | public function testGetDescription() 45 | { 46 | $text = 'Creates bought together product suggestions'; 47 | $this->assertEquals( $text, $this->object->getDescription() ); 48 | } 49 | 50 | 51 | public function testRun() 52 | { 53 | $stub = $this->getMockBuilder( '\\Aimeos\\MShop\\Product\\Manager\\Standard' ) 54 | ->setConstructorArgs( [$this->context] ) 55 | ->onlyMethods( ['save', 'type'] ) 56 | ->getMock(); 57 | 58 | $stub->method( 'type' )->willReturn( ['product'] ); 59 | $stub->expects( $this->atLeastOnce() )->method( 'save' ); 60 | 61 | $stub = new \Aimeos\MShop\Common\Manager\Decorator\Lists( $stub, $this->context ); 62 | 63 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Product\\Manager\\Standard', $stub ); 64 | 65 | $this->object->run(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Xml/Import/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | 25 | $this->object = new \Aimeos\Controller\Jobs\Xml\Import\Standard( $this->context, $aimeos ); 26 | } 27 | 28 | 29 | protected function tearDown() : void 30 | { 31 | unset( $this->object, $this->context ); 32 | \Aimeos\MShop::cache( false ); 33 | } 34 | 35 | 36 | public function testGetName() 37 | { 38 | $this->assertEquals( 'All XML import', $this->object->getName() ); 39 | } 40 | 41 | 42 | public function testGetDescription() 43 | { 44 | $text = 'Executes all XML importers and rebuild the index'; 45 | $this->assertEquals( $text, $this->object->getDescription() ); 46 | } 47 | 48 | 49 | public function testRun() 50 | { 51 | $config = $this->context->config(); 52 | $config->set( 'controller/jobs/group/import/xml/location', __DIR__ . '/_testfiles' ); 53 | $config->set( 'controller/jobs/customer/import/xml/location', __DIR__ . '/_testfiles' ); 54 | $config->set( 'controller/jobs/attribute/import/xml/location', __DIR__ . '/_testfiles' ); 55 | $config->set( 'controller/jobs/product/import/xml/location', __DIR__ . '/_testfiles' ); 56 | $config->set( 'controller/jobs/supplier/import/xml/location', __DIR__ . '/_testfiles' ); 57 | $config->set( 'controller/jobs/catalog/import/xml/location', __DIR__ . '/_testfiles' ); 58 | 59 | $this->object->run(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Subscription/Process/Base.php: -------------------------------------------------------------------------------- 1 | context(); 35 | $interface = \Aimeos\Controller\Jobs\Common\Subscription\Process\Processor\Iface::class; 36 | 37 | foreach( $pnames as $pname ) 38 | { 39 | if( ctype_alnum( $pname ) === false ) { 40 | throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $pname ), 400 ); 41 | } 42 | 43 | $name = $context->config()->get( 'controller/jobs/subscription/process/processor/' . $pname . '/name', 'Standard' ); 44 | 45 | if( ctype_alnum( $name ) === false ) { 46 | throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $name ), 400 ); 47 | } 48 | 49 | $classname = '\\Aimeos\\Controller\\Jobs\\Common\\Subscription\\Process\\Processor\\' . ucfirst( $pname ) . '\\' . $name; 50 | 51 | $list[$pname] = \Aimeos\Utils::create( $classname, [$context], $interface ); 52 | } 53 | 54 | return $list; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Media/Scale/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Media\Scale\Standard( $context, $aimeos ); 25 | } 26 | 27 | 28 | protected function tearDown() : void 29 | { 30 | unset( $this->object ); 31 | } 32 | 33 | 34 | public function testGetName() 35 | { 36 | $this->assertEquals( 'Rescale product images', $this->object->getName() ); 37 | } 38 | 39 | 40 | public function testGetDescription() 41 | { 42 | $text = 'Rescales product images to the new sizes'; 43 | $this->assertEquals( $text, $this->object->getDescription() ); 44 | } 45 | 46 | 47 | public function testRun() 48 | { 49 | $context = \TestHelper::context(); 50 | $aimeos = \TestHelper::getAimeos(); 51 | 52 | $managerStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Media\\Manager\\Standard' ) 53 | ->onlyMethods( array( 'save', 'scale', 'type' ) ) 54 | ->setConstructorArgs( array( $context ) ) 55 | ->getMock(); 56 | 57 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Media\\Manager\\Standard', $managerStub ); 58 | 59 | $managerStub->method( 'type' )->willReturn([ 'media'] ); 60 | $managerStub->expects( $this->atLeast( 1 ) )->method( 'save' ); 61 | $managerStub->expects( $this->atLeast( 1 ) )->method( 'scale' )->willReturnArgument( 0 ); 62 | 63 | 64 | $object = new \Aimeos\Controller\Jobs\Media\Scale\Standard( $context, $aimeos ); 65 | $object->run(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /templates/controller/jobs/catalog/export/sitemap-items.php: -------------------------------------------------------------------------------- 1 | encoder(); 9 | 10 | $treeTarget = $this->config( 'client/html/catalog/tree/url/target' ); 11 | $treeCntl = $this->config( 'client/html/catalog/tree/url/controller', 'catalog' ); 12 | $treeAction = $this->config( 'client/html/catalog/tree/url/action', 'list' ); 13 | $treeFilter = array_flip( $this->config( 'client/html/catalog/tree/url/filter', [] ) ); 14 | $treeConfig = $this->config( 'client/html/catalog/tree/url/config', [] ); 15 | $treeConfig['absoluteUri'] = true; 16 | 17 | $locales = $this->get( 'siteLocales', map() ); 18 | $sites = $locales->groupBy( 'locale.siteid' ); 19 | 20 | 21 | echo '' . "\n"; 22 | echo '' . "\n"; 23 | 24 | 25 | foreach( $this->get( 'siteItems', [] ) as $id => $item ) 26 | { 27 | $langIds = []; 28 | $date = str_replace( ' ', 'T', $item->getTimeModified() ?? '' ) . date( 'P' ); 29 | 30 | foreach( $locales as $locale ) 31 | { 32 | $langId = $locale->getLanguageId(); 33 | 34 | if( isset( $langIds[$langId] ) ) { 35 | continue; 36 | } 37 | $langIds[$langId] = true; 38 | 39 | $name = $item->getName( 'url', $langId ); 40 | $params = ['f_name' => \Aimeos\Base\Str::slug( $name ), 'f_catid' => $id]; 41 | 42 | if( count( $sites ) > 1 ) { 43 | $params['site'] = $locale->getSiteCode(); 44 | } 45 | 46 | if( count( $locales ) > 1 ) { 47 | $params['locale'] = $langId; 48 | } 49 | 50 | $url = $this->url( $item->getTarget() ?: $treeTarget, $treeCntl, $treeAction, array_diff_key( $params, $treeFilter ), [], $treeConfig ); 51 | 52 | echo '' . $enc->xml( $url ) . '' . $date . "\n"; 53 | } 54 | } 55 | 56 | echo "\n"; -------------------------------------------------------------------------------- /tests/Controller/Jobs/Index/Rebuild/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Index\Rebuild\Standard( $context, $aimeos ); 26 | } 27 | 28 | 29 | protected function tearDown() : void 30 | { 31 | \Aimeos\MShop::cache( false ); 32 | unset( $this->object ); 33 | } 34 | 35 | 36 | public function testGetName() 37 | { 38 | $this->assertEquals( 'Index rebuild', $this->object->getName() ); 39 | } 40 | 41 | 42 | public function testGetDescription() 43 | { 44 | $text = 'Rebuilds the index for searching products'; 45 | $this->assertEquals( $text, $this->object->getDescription() ); 46 | } 47 | 48 | 49 | public function testRun() 50 | { 51 | $context = \TestHelper::context(); 52 | $aimeos = \TestHelper::getAimeos(); 53 | 54 | $indexManagerStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Index\\Manager\\Standard' ) 55 | ->onlyMethods( array( 'rebuild', 'cleanup' ) ) 56 | ->setConstructorArgs( array( $context ) ) 57 | ->getMock(); 58 | 59 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Index\\Manager\\Standard', $indexManagerStub ); 60 | 61 | $indexManagerStub->expects( $this->once() )->method( 'rebuild' )->willReturnSelf(); 62 | $indexManagerStub->expects( $this->once() )->method( 'cleanup' )->willReturnSelf(); 63 | 64 | $object = new \Aimeos\Controller\Jobs\Index\Rebuild\Standard( $context, $aimeos ); 65 | $object->run(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Coupon/Import/Csv/Processor/Code/Standard.php: -------------------------------------------------------------------------------- 1 | context(), 'coupon/code' ); 45 | $map = $this->getMappedChunk( $data, $this->getMapping() ); 46 | 47 | foreach( $map as $list ) 48 | { 49 | if( trim( $list['coupon.code.code'] ) == '' ) { 50 | continue; 51 | } 52 | 53 | $item = $manager->save( $item->fromArray( $list ) ); 54 | } 55 | 56 | return $this->object()->process( $item, $data ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/items-partial-text-standard.php: -------------------------------------------------------------------------------- 1 | encoder() 22 | 23 | ?> 24 | 25 | listItems as $listItem ) : ?> 26 | getRefItem() ) : ?> 27 | 30 | xml( $refItem->getType() ) ?>]]> 31 | xml( $refItem->getLanguageId() ) ?>]]> 32 | xml( $refItem->getLabel() ) ?>]]> 33 | xml( $refItem->getContent() ) ?>]]> 34 | xml( $refItem->getStatus() ) ?>]]> 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Export/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $this->aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Product\Export\Standard( $this->context, $this->aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | $this->object = null; 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Product export', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Exports all available products'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $this->context->config()->set( 'controller/jobs/product/export/filename', 'aimeos-products-%1$d.xml' ); 53 | 54 | $this->object->run(); 55 | 56 | $ds = DIRECTORY_SEPARATOR; 57 | $this->assertFileExists( 'tmp' . $ds . 'aimeos-products-1.xml' ); 58 | $this->assertFileExists( 'tmp' . $ds . 'aimeos-products-2.xml' ); 59 | 60 | $file1 = file_get_contents( 'tmp' . $ds . 'aimeos-products-1.xml' ); 61 | $file2 = file_get_contents( 'tmp' . $ds . 'aimeos-products-2.xml' ); 62 | 63 | unlink( 'tmp' . $ds . 'aimeos-products-1.xml' ); 64 | unlink( 'tmp' . $ds . 'aimeos-products-2.xml' ); 65 | 66 | $this->assertStringContainsString( 'CNE', $file2 ); 67 | $this->assertStringContainsString( 'U:BUNDLE', $file2 ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Admin/Log/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Admin\Log\Standard( $this->context, $aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MAdmin::cache( false ); 33 | unset( $this->object, $this->context ); 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Log cleanup', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Removes the old log entries from the database and archives them (optional)'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $config = $this->context->config(); 53 | $config->set( 'controller/jobs/admin/log/limit-days', 0 ); 54 | 55 | $mock = $this->getMockBuilder( '\\Aimeos\\MAdmin\\Log\\Manager\\Standard' ) 56 | ->setConstructorArgs( [$this->context] ) 57 | ->onlyMethods( ['delete'] ) 58 | ->getMock(); 59 | 60 | $mock->expects( $this->atLeastOnce() )->method( 'delete' ); 61 | 62 | \Aimeos\MAdmin::inject( '\\Aimeos\\MAdmin\\Log\\Manager\\Standard', $mock ); 63 | 64 | $this->object->run(); 65 | 66 | $expected = dirname( __DIR__, 4) . '/tmp/logs/aimeos_' . date( 'Y-m-d' ) . '.log'; 67 | $this->assertFileExists( $expected ); 68 | 69 | unlink( $expected ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Xml/_testfiles/catalog_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Group/Import/Xml/StandardTest.php: -------------------------------------------------------------------------------- 1 | fs( 'fs-import' ); 24 | $fs->has( 'group/unittest' ) ?: $fs->mkdir( 'group/unittest' ); 25 | $fs->writef( 'group/unittest/group_1.xml', __DIR__ . '/_testfiles/group_1.xml' ); 26 | $fs->writef( 'group/unittest/group_2.xml', __DIR__ . '/_testfiles/group_2.xml' ); 27 | } 28 | 29 | 30 | protected function setUp() : void 31 | { 32 | \Aimeos\MShop::cache( true ); 33 | 34 | $this->context = \TestHelper::context(); 35 | $this->aimeos = \TestHelper::getAimeos(); 36 | 37 | $this->object = new \Aimeos\Controller\Jobs\Group\Import\Xml\Standard( $this->context, $this->aimeos ); 38 | } 39 | 40 | 41 | protected function tearDown() : void 42 | { 43 | \Aimeos\MShop::cache( false ); 44 | unset( $this->object, $this->context, $this->aimeos ); 45 | } 46 | 47 | 48 | public function testGetName() 49 | { 50 | $this->assertEquals( 'Groups import XML', $this->object->getName() ); 51 | } 52 | 53 | 54 | public function testGetDescription() 55 | { 56 | $text = 'Imports new and updates existing groups from XML files'; 57 | $this->assertEquals( $text, $this->object->getDescription() ); 58 | } 59 | 60 | 61 | public function testRun() 62 | { 63 | $this->object->run(); 64 | 65 | $manager = \Aimeos\MShop::create( $this->context, 'group' ); 66 | $item = $manager->find( 'test' ); 67 | $manager->delete( $item ); 68 | 69 | $this->assertEquals( 'Test group', $item->getLabel() ); 70 | $this->assertEquals( 'test', $item->getCode() ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/sitemap-items.php: -------------------------------------------------------------------------------- 1 | encoder(); 9 | 10 | $detailTarget = $this->config( 'client/html/catalog/detail/url/target' ); 11 | $detailCntl = $this->config( 'client/html/catalog/detail/url/controller', 'catalog' ); 12 | $detailAction = $this->config( 'client/html/catalog/detail/url/action', 'detail' ); 13 | $detailFilter = array_flip( $this->config( 'client/html/catalog/detail/url/filter', ['d_prodid'] ) ); 14 | $detailConfig = $this->config( 'client/html/catalog/detail/url/config', [] ); 15 | $detailConfig['absoluteUri'] = true; 16 | 17 | $locales = $this->get( 'siteLocales', map() ); 18 | $sites = $locales->groupBy( 'locale.siteid' ); 19 | 20 | 21 | echo '' . "\n"; 22 | echo '' . "\n"; 23 | 24 | 25 | foreach( $this->get( 'siteItems', [] ) as $id => $item ) 26 | { 27 | $langIds = []; 28 | $slug = $item->getName( 'url' ); 29 | $date = str_replace( ' ', 'T', $item->getTimeModified() ?? '' ) . date( 'P' ); 30 | 31 | foreach( $locales as $locale ) 32 | { 33 | $langId = $locale->getLanguageId(); 34 | 35 | if( isset( $langIds[$langId] ) ) { 36 | continue; 37 | } 38 | $langIds[$langId] = true; 39 | 40 | $name = \Aimeos\Base\Str::slug( $item->getName( 'url', $langId ) ); 41 | $params = ['path' => $name, 'd_name' => $name, 'd_prodid' => $id, 'd_pos' => '', 'site' => $locale->getSiteCode()]; 42 | 43 | if( count( $locales ) > 1 ) 44 | { 45 | $params['locale'] = $langId; 46 | $params['currency'] = $locale->getCurrencyId(); 47 | } 48 | 49 | $url = $this->url( $item->getTarget() ?: $detailTarget, $detailCntl, $detailAction, array_diff_key( $params, $detailFilter ), [], $detailConfig ); 50 | 51 | echo '' . $enc->xml( $url ) . '' . $date . "\n"; 52 | } 53 | } 54 | 55 | echo "\n"; -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Processor/Lists/Standard.php: -------------------------------------------------------------------------------- 1 | getProcessors() as $proc ) { 44 | $proc->finish(); 45 | } 46 | } 47 | 48 | 49 | /** 50 | * Updates the given item using the data from the DOM node 51 | * 52 | * @param \Aimeos\MShop\Common\Item\Iface $item Item which should be updated 53 | * @param \DOMNode $node XML document node containing a list of nodes to process 54 | * @return \Aimeos\MShop\Common\Item\Iface Updated item 55 | */ 56 | public function process( \Aimeos\MShop\Common\Item\Iface $item, \DOMNode $node ) : \Aimeos\MShop\Common\Item\Iface 57 | { 58 | foreach( $node->childNodes as $listNode ) 59 | { 60 | if( $listNode->nodeName[0] === '#' ) { 61 | continue; 62 | } 63 | 64 | $item = $this->getProcessor( 'lists/' . $listNode->nodeName )->process( $item, $listNode ); 65 | } 66 | 67 | return $item; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /config/controller.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'attribute' => [ 6 | 'import' => [ 7 | 'xml' => [ 8 | 'domains' => [ 9 | 'attribute/property' => 'attribute/property', 10 | 'media' => 'media', 11 | 'media/property' => 'media/property', 12 | 'price' => 'price', 13 | 'price/property' => 'price/property', 14 | 'text' => 'text' 15 | ] 16 | ] 17 | ] 18 | ], 19 | 'catalog' => [ 20 | 'import' => [ 21 | 'xml' => [ 22 | 'domains' => [ 23 | 'media' => 'media', 24 | 'media/property' => 'media/property', 25 | 'product' => 'product', 26 | 'text' => 'text' 27 | ] 28 | ] 29 | ] 30 | ], 31 | 'product' => [ 32 | 'import' => [ 33 | 'csv' => [ 34 | 'domains' => [ 35 | 'attribute' => 'attribute', 36 | 'catalog' => 'catalog', 37 | 'media' => 'media', 38 | 'price' => 'price', 39 | 'product' => 'product', 40 | 'product/property' => 'product/property', 41 | 'supplier' => 'supplier', 42 | 'text' => 'text', 43 | ], 44 | ], 45 | 'xml' => [ 46 | 'domains' => [ 47 | 'attribute' => 'attribute', 48 | 'attribute/property' => 'attribute/property', 49 | 'catalog' => 'catalog', 50 | 'media' => 'media', 51 | 'media/property' => 'media/property', 52 | 'price' => 'price', 53 | 'price/property' => 'price/property', 54 | 'product' => 'product', 55 | 'product/property' => 'product/property', 56 | 'supplier' => 'supplier', 57 | 'text' => 'text' 58 | ] 59 | ] 60 | ] 61 | ], 62 | 'subscription' => [ 63 | 'process' => [ 64 | 'processors' => [ 65 | 'Email' => 'Email', 66 | ], 67 | ], 68 | ], 69 | 'supplier' => [ 70 | 'import' => [ 71 | 'xml' => [ 72 | 'domains' => [ 73 | 'supplier/address' => 'supplier/address', 74 | 'media' => 'media', 75 | 'media/property' => 'media/property', 76 | 'product' => 'product', 77 | 'text' => 'text' 78 | ] 79 | ] 80 | ] 81 | ], 82 | ] 83 | ]; 84 | -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/items-body-standard.php: -------------------------------------------------------------------------------- 1 | encoder() 9 | 10 | ?> 11 | '; ?> 12 | 13 | get( 'exportItems', [] ) as $item ) : ?> 14 | 15 | xml( $item->getType() ) ?>]]> 16 | xml( $item->getCode() ) ?>]]> 17 | xml( $item->getLabel() ) ?>]]> 18 | xml( $item->boost() ) ?>]]> 19 | xml( $item->getStatus() ) ?>]]> 20 | xml( json_encode( $item->getConfig() ) ) ?>]]> 21 | xml( str_replace( ' ', 'T', $item->getDateStart() ?? '' ) ) ?>]]> 22 | xml( str_replace( ' ', 'T', $item->getDateEnd() ?? '' ) ) ?>]]> 23 | 24 | getDomains() as $domain ) : ?> 25 | partial( 26 | 'product/export/items-partial-' . str_replace( '/', '', $domain ) . '-standard', 27 | ['listItems' => $item->getListItems( $domain )] 28 | ) ?> 29 | 30 | 31 | 32 | getPropertyItems() as $propItem ) : ?> 33 | 34 | xml( $propItem->getType() ) ?>]]> 35 | xml( $propItem->getLanguageId() ) ?>]]> 36 | xml( $propItem->getValue() ) ?>]]> 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Subscription/Process/Processor/Iface.php: -------------------------------------------------------------------------------- 1 | prodmap[$code] ) ) { 47 | return $this->prodmap[$code]; 48 | } 49 | 50 | $manager = \Aimeos\MShop::create( $this->context(), 'product' ); 51 | 52 | $search = $manager->filter(); 53 | $search->setConditions( $search->compare( '==', 'product.code', $code ) ); 54 | 55 | if( ( $item = $manager->search( $search )->first() ) !== null ) 56 | { 57 | $this->prodmap[$code] = $item->getId(); 58 | return $this->prodmap[$code]; 59 | } 60 | } 61 | 62 | 63 | /** 64 | * Adds the product ID to the cache 65 | * 66 | * @param \Aimeos\MShop\Common\Item\Iface $item Product object 67 | */ 68 | public function set( \Aimeos\MShop\Common\Item\Iface $item ) 69 | { 70 | $this->prodmap[$item->getCode()] = $item->getId(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Order/Cleanup/Unpaid/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Order\Cleanup\Unpaid\Standard( $context, $aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | unset( $this->object ); 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Removes unpaid orders', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Deletes unpaid orders to keep the database clean'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $context = \TestHelper::context(); 53 | $aimeos = \TestHelper::getAimeos(); 54 | 55 | 56 | $orderManagerStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Order\\Manager\\Standard' ) 57 | ->onlyMethods( ['iterate', 'delete', 'unblock'] ) 58 | ->setConstructorArgs( array( $context ) ) 59 | ->getMock(); 60 | 61 | 62 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Order\\Manager\\Standard', $orderManagerStub ); 63 | 64 | 65 | $orderItem = $orderManagerStub->create()->setId( 2 ); 66 | 67 | $orderManagerStub->expects( $this->exactly( 2 ) )->method( 'iterate' ) 68 | ->willReturn( map( [$orderItem->getId() => $orderItem] ), null ); 69 | 70 | $orderManagerStub->expects( $this->once() )->method( 'delete' ); 71 | 72 | $orderManagerStub->expects( $this->once() )->method( 'unblock' ); 73 | 74 | 75 | $object = new \Aimeos\Controller\Jobs\Order\Cleanup\Unpaid\Standard( $context, $aimeos ); 76 | $object->run(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Customer/Import/Csv/Processor/Address/Standard.php: -------------------------------------------------------------------------------- 1 | context(); 45 | $manager = \Aimeos\MShop::create( $context, 'customer' ); 46 | 47 | $pos = 0; 48 | $map = $this->getMappedChunk( $data, $this->getMapping() ); 49 | $addresses = $customer->getAddressItems(); 50 | 51 | foreach( $map as $entry ) 52 | { 53 | $key = $addresses->firstKey(); 54 | $address = $addresses->pull( $key ) ?? $manager->createAddressItem(); 55 | $address->setPosition( $pos++ )->fromArray( $entry ); 56 | 57 | $customer->addAddressItem( $address, $key ); 58 | } 59 | 60 | $customer->deleteAddressItems( $addresses ); 61 | 62 | return $this->object()->process( $customer, $data ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Order/Cleanup/Unfinished/StandardTest.php: -------------------------------------------------------------------------------- 1 | object = new \Aimeos\Controller\Jobs\Order\Cleanup\Unfinished\Standard( $context, $aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | unset( $this->object ); 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Removes unfinished orders', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Deletes unfinished orders an makes their products and coupon codes available again'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $context = \TestHelper::context(); 53 | $aimeos = \TestHelper::getAimeos(); 54 | 55 | 56 | $orderManagerStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Order\\Manager\\Standard' ) 57 | ->onlyMethods( ['iterate', 'delete', 'unblock'] ) 58 | ->setConstructorArgs( array( $context ) ) 59 | ->getMock(); 60 | 61 | 62 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Order\\Manager\\Standard', $orderManagerStub ); 63 | 64 | 65 | $orderItem = $orderManagerStub->create()->setId( 2 ); 66 | 67 | $orderManagerStub->expects( $this->exactly( 2 ) )->method( 'iterate' ) 68 | ->willReturn( map( [$orderItem->getId() => $orderItem] ), null ); 69 | 70 | $orderManagerStub->expects( $this->once() )->method( 'delete' ); 71 | 72 | $orderManagerStub->expects( $this->once() )->method( 'unblock' ); 73 | 74 | 75 | $object = new \Aimeos\Controller\Jobs\Order\Cleanup\Unfinished\Standard( $context, $aimeos ); 76 | $object->run(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Xml/_testfiles/catalog_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/items-partial-price-standard.php: -------------------------------------------------------------------------------- 1 | encoder() 22 | 23 | ?> 24 | 25 | listItems as $listItem ) : ?> 26 | getRefItem() ) : ?> 27 | 30 | xml( $refItem->getType() ) ?>]]> 31 | xml( $refItem->getCurrencyId() ) ?>]]> 32 | xml( $refItem->getTaxrate() ) ?>]]> 33 | xml( $refItem->getQuantity() ) ?>]]> 34 | xml( $refItem->getValue() ) ?>]]> 35 | xml( $refItem->getCosts() ) ?>]]> 36 | xml( $refItem->getRebate() ) ?>]]> 37 | xml( $refItem->getLabel() ) ?>]]> 38 | xml( $refItem->getStatus() ) ?>]]> 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Import/Xml/Processor/Group/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 21 | $this->object = new \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Group\Standard( $this->context ); 22 | } 23 | 24 | 25 | protected function tearDown() : void 26 | { 27 | unset( $this->object, $this->context ); 28 | } 29 | 30 | 31 | public function testProcess() 32 | { 33 | $dom = new \DOMDocument(); 34 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create(); 35 | 36 | $dom->loadXML( ' 37 | 38 | 39 | 40 | ' ); 41 | 42 | $customer = $this->object->process( $customer, $dom->firstChild ); 43 | 44 | $items = $customer->getGroups(); 45 | $this->assertEquals( 2, count( $items ) ); 46 | } 47 | 48 | 49 | public function testProcessUpdate() 50 | { 51 | $dom = new \DOMDocument(); 52 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create()->setGroups( [123] ); 53 | 54 | $dom->loadXML( ' 55 | 56 | 57 | 58 | ' ); 59 | 60 | $customer = $this->object->process( $customer, $dom->firstChild ); 61 | 62 | $items = $customer->getGroups(); 63 | $this->assertEquals( 2, count( $items ) ); 64 | } 65 | 66 | 67 | public function testProcessDelete() 68 | { 69 | $dom = new \DOMDocument(); 70 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create()->setGroups( [123, 456] ); 71 | 72 | $dom->loadXML( ' 73 | 74 | 75 | ' ); 76 | 77 | $customer = $this->object->process( $customer, $dom->firstChild ); 78 | 79 | $items = $customer->getGroups(); 80 | $this->assertEquals( 1, count( $items ) ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Catalog/Import/Csv/BaseTest.php: -------------------------------------------------------------------------------- 1 | object = new TestAbstract( $context, $aimeos ); 25 | } 26 | 27 | 28 | protected function tearDown() : void 29 | { 30 | \Aimeos\MShop::cache( false ); 31 | } 32 | 33 | 34 | public function testGetCacheInvalidType() 35 | { 36 | $this->expectException( \LogicException::class ); 37 | $this->object->getCachePublic( '$' ); 38 | } 39 | 40 | 41 | public function testGetCacheInvalidClass() 42 | { 43 | $this->expectException( \LogicException::class ); 44 | $this->object->getCachePublic( 'unknown' ); 45 | } 46 | 47 | 48 | public function testGetProcessors() 49 | { 50 | $processor = $this->object->getProcessorsPublic( array( 'media' => [] ) ); 51 | 52 | $this->assertInstanceOf( '\\Aimeos\\Controller\\Jobs\\Common\\Catalog\\Import\\Csv\\Processor\\Iface', $processor ); 53 | } 54 | 55 | 56 | public function testGetProcessorsInvalidType() 57 | { 58 | $this->expectException( \LogicException::class ); 59 | $this->object->getProcessorsPublic( array( '$' => [] ) ); 60 | } 61 | 62 | 63 | public function testGetProcessorsInvalidClass() 64 | { 65 | $this->expectException( \LogicException::class ); 66 | $this->object->getProcessorsPublic( array( 'unknown' => [] ) ); 67 | } 68 | 69 | 70 | public function testGetProcessorsInvalidInterface() 71 | { 72 | $this->expectException( \LogicException::class ); 73 | $this->object->getProcessorsPublic( array( 'unknown' => [] ) ); 74 | } 75 | } 76 | 77 | 78 | class TestAbstract 79 | extends \Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Base 80 | { 81 | public function getCachePublic( $type, $name = null ) 82 | { 83 | return $this->getCache( $type, $name ); 84 | } 85 | 86 | 87 | public function getProcessorsPublic( array $mappings ) 88 | { 89 | return $this->getProcessors( $mappings ); 90 | } 91 | } 92 | 93 | 94 | class TestInvalid 95 | { 96 | } 97 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Supplier/Import/Csv/BaseTest.php: -------------------------------------------------------------------------------- 1 | object = new TestAbstract( $context, $aimeos ); 25 | } 26 | 27 | 28 | protected function tearDown() : void 29 | { 30 | \Aimeos\MShop::cache( false ); 31 | } 32 | 33 | 34 | public function testGetCacheInvalidType() 35 | { 36 | $this->expectException( \LogicException::class ); 37 | $this->object->getCachePublic( '$' ); 38 | } 39 | 40 | 41 | public function testGetCacheInvalidClass() 42 | { 43 | $this->expectException( \LogicException::class ); 44 | $this->object->getCachePublic( 'unknown' ); 45 | } 46 | 47 | 48 | public function testGetProcessors() 49 | { 50 | $processor = $this->object->getProcessorsPublic( array( 'media' => [] ) ); 51 | 52 | $this->assertInstanceOf( '\\Aimeos\\Controller\\Jobs\\Common\\Supplier\\Import\\Csv\\Processor\\Iface', $processor ); 53 | } 54 | 55 | 56 | public function testGetProcessorsInvalidType() 57 | { 58 | $this->expectException( \LogicException::class ); 59 | $this->object->getProcessorsPublic( array( '$' => [] ) ); 60 | } 61 | 62 | 63 | public function testGetProcessorsInvalidClass() 64 | { 65 | $this->expectException( \LogicException::class ); 66 | $this->object->getProcessorsPublic( array( 'unknown' => [] ) ); 67 | } 68 | 69 | 70 | public function testGetProcessorsInvalidInterface() 71 | { 72 | $this->expectException( \LogicException::class ); 73 | $this->object->getProcessorsPublic( array( 'unknown' => [] ) ); 74 | } 75 | } 76 | 77 | 78 | class TestAbstract 79 | extends \Aimeos\Controller\Jobs\Common\Supplier\Import\Csv\Base 80 | { 81 | public function getCachePublic( $type, $name = null ) 82 | { 83 | return $this->getCache( $type, $name ); 84 | } 85 | 86 | 87 | public function getProcessorsPublic( array $mappings ) 88 | { 89 | return $this->getProcessors( $mappings ); 90 | } 91 | } 92 | 93 | 94 | class TestInvalid 95 | { 96 | } 97 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Supplier/Import/Csv/Processor/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 39 | $this->mapping = $mapping; 40 | $this->object = $object; 41 | } 42 | 43 | 44 | /** 45 | * Returns the context item 46 | * 47 | * @return \Aimeos\MShop\ContextIface Context object 48 | */ 49 | protected function context() : \Aimeos\MShop\ContextIface 50 | { 51 | return $this->context; 52 | } 53 | 54 | 55 | /** 56 | * Returns the mapping list 57 | * 58 | * @return array Associative list of field positions in CSV as keys and domain item keys as values 59 | */ 60 | protected function getMapping() : array 61 | { 62 | return $this->mapping; 63 | } 64 | 65 | 66 | /** 67 | * Returns the decorated processor object 68 | * 69 | * @return \Aimeos\Controller\Jobs\Common\Supplier\Import\Csv\Processor\Iface Processor object 70 | * @throws \Aimeos\Controller\Jobs\Exception If no processor object is available 71 | */ 72 | protected function object() : Iface 73 | { 74 | if( $this->object === null ) 75 | { 76 | throw new \Aimeos\Controller\Jobs\Exception( 'No processor object available' ); 77 | } 78 | 79 | return $this->object; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Coupon/Import/Csv/Processor/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 39 | $this->mapping = $mapping; 40 | $this->object = $object; 41 | } 42 | 43 | 44 | /** 45 | * Returns the context item 46 | * 47 | * @return \Aimeos\MShop\ContextIface Context object 48 | */ 49 | protected function context() : \Aimeos\MShop\ContextIface 50 | { 51 | return $this->context; 52 | } 53 | 54 | 55 | /** 56 | * Returns the mapping list 57 | * 58 | * @return array Associative list of field positions in CSV as keys and domain item keys as values 59 | */ 60 | protected function getMapping() : array 61 | { 62 | return $this->mapping; 63 | } 64 | 65 | 66 | /** 67 | * Returns the decorated processor object 68 | * 69 | * @return \Aimeos\Controller\Jobs\Common\Coupon\Import\Csv\Processor\Iface Processor object 70 | * @throws \Aimeos\Controller\Jobs\Exception If no processor object is available 71 | */ 72 | protected function object() : \Aimeos\Controller\Jobs\Common\Coupon\Import\Csv\Processor\Iface 73 | { 74 | if( $this->object === null ) { 75 | throw new \Aimeos\Controller\Jobs\Exception( 'No processor object available' ); 76 | } 77 | 78 | return $this->object; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Processor/Address/Standard.php: -------------------------------------------------------------------------------- 1 | context(), $item->getResourceType() ); 47 | $addrItems = $item->getAddressItems()->reverse(); 48 | 49 | foreach( $node->childNodes as $addrNode ) 50 | { 51 | if( $addrNode->nodeName !== 'addressitem' ) { 52 | continue; 53 | } 54 | 55 | $list = []; 56 | 57 | foreach( $addrNode->childNodes as $tagNode ) { 58 | $list[$tagNode->nodeName] = \Aimeos\Base\Str::decode( $tagNode->nodeValue ); 59 | } 60 | 61 | if( ( $addrItem = $addrItems->pop() ) !== null ) { 62 | $addrItems->remove( $addrItem->getId() ); 63 | } else { 64 | $addrItem = $manager->createAddressItem(); 65 | } 66 | 67 | $item = $item->addAddressItem( $addrItem->fromArray( $list ), $addrItem->getId() ); 68 | } 69 | 70 | return $item->deleteAddressItems( $addrItems->toArray() ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Types.php: -------------------------------------------------------------------------------- 1 | typeMap[$path][$domain][$code] = $code; 45 | return $this; 46 | } 47 | 48 | 49 | /** 50 | * Stores all types for which no type items exist yet 51 | * 52 | * @return self Same object for method chaining 53 | */ 54 | protected function saveTypes() : self 55 | { 56 | foreach( $this->typeMap as $path => $list ) 57 | { 58 | $manager = \Aimeos\MShop::create( $this->context(), $path ); 59 | $prefix = str_replace( '/', '.', $path ); 60 | 61 | foreach( $list as $codes ) 62 | { 63 | $manager->begin(); 64 | 65 | try 66 | { 67 | $types = $items = []; 68 | $search = $manager->filter()->add( [$prefix . '.code' => $codes] )->slice( 0, 10000 ); 69 | 70 | foreach( $manager->search( $search ) as $item ) { 71 | $types[] = $item->getCode(); 72 | } 73 | 74 | foreach( array_diff( $codes, $types ) as $code ) { 75 | $items[] = $manager->create()->setCode( $code )->setLabel( $code ); 76 | } 77 | 78 | $manager->save( $items, false ); 79 | $manager->commit(); 80 | } 81 | catch( \Exception $e ) 82 | { 83 | $manager->rollback(); 84 | 85 | $msg = 'Error saving types: ' . $e->getMessage() . PHP_EOL . $e->getTraceAsString(); 86 | $this->context()->logger()->error( $msg, 'import' ); 87 | } 88 | } 89 | } 90 | 91 | return $this; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Cache/Catalog/Standard.php: -------------------------------------------------------------------------------- 1 | categories = $manager->search( $manager->filter() )->col( null, 'catalog.code' )->toArray(); 48 | } 49 | 50 | 51 | /** 52 | * Returns the catalog ID for the given code and type 53 | * 54 | * @param string $code Category code 55 | * @param string|null $type Not used 56 | * @return string|null Catalog ID or null if not found 57 | */ 58 | public function get( string $code, ?string $type = null ) 59 | { 60 | if( isset( $this->categories[$code] ) ) { 61 | return $this->categories[$code]; 62 | } 63 | 64 | $manager = \Aimeos\MShop::create( $this->context(), 'catalog' ); 65 | $search = $manager->filter()->add( 'catalog.code', '==', $code ); 66 | 67 | if( $item = $manager->search( $search )->first() ) { 68 | $this->categories[$code] = $item; 69 | } 70 | 71 | return $item; 72 | } 73 | 74 | 75 | /** 76 | * Adds the catalog item to the cache 77 | * 78 | * @param \Aimeos\MShop\Common\Item\Iface $item Catalog object 79 | */ 80 | public function set( \Aimeos\MShop\Common\Item\Iface $item ) 81 | { 82 | $this->categories[$item->getCode()] = $item; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Attribute/Import/Xml/StandardTest.php: -------------------------------------------------------------------------------- 1 | fs( 'fs-import' ); 24 | $fs->has( 'attribute/unittest' ) ?: $fs->mkdir( 'attribute/unittest' ); 25 | $fs->writef( 'attribute/unittest/attribute_1.xml', __DIR__ . '/_testfiles/attribute_1.xml' ); 26 | $fs->writef( 'attribute/unittest/attribute_2.xml', __DIR__ . '/_testfiles/attribute_2.xml' ); 27 | 28 | $fs = $context->fs( 'fs-media' ); 29 | $fs->has( 'path/to' ) ?: $fs->mkdir( 'path/to' ); 30 | $fs->write( 'path/to/file2.jpg', 'test' ); 31 | $fs->write( 'path/to/file.jpg', 'test' ); 32 | 33 | $fs = $context->fs( 'fs-mimeicon' ); 34 | $fs->write( 'unknown.png', 'icon' ); 35 | } 36 | 37 | 38 | protected function setUp() : void 39 | { 40 | $this->context = \TestHelper::context(); 41 | $this->aimeos = \TestHelper::getAimeos(); 42 | 43 | $this->object = new \Aimeos\Controller\Jobs\Attribute\Import\Xml\Standard( $this->context, $this->aimeos ); 44 | } 45 | 46 | 47 | protected function tearDown() : void 48 | { 49 | unset( $this->object, $this->context, $this->aimeos ); 50 | } 51 | 52 | 53 | public function testGetName() 54 | { 55 | $this->assertEquals( 'Attribute import XML', $this->object->getName() ); 56 | } 57 | 58 | 59 | public function testGetDescription() 60 | { 61 | $text = 'Imports new and updates existing attributes from XML files'; 62 | $this->assertEquals( $text, $this->object->getDescription() ); 63 | } 64 | 65 | 66 | public function testRun() 67 | { 68 | $this->object->run(); 69 | 70 | $manager = \Aimeos\MShop::create( $this->context, 'attribute' ); 71 | $item = $manager->find( 'unittest-xml', ['attribute/property', 'media', 'price', 'text'], 'product', 'color' ); 72 | $manager->delete( $item->getId() ); 73 | 74 | $this->assertEquals( 'Test attribute 2', $item->getLabel() ); 75 | $this->assertEquals( 1, count( $item->getRefItems( 'media' ) ) ); 76 | $this->assertEquals( 1, count( $item->getRefItems( 'price' ) ) ); 77 | $this->assertEquals( 1, count( $item->getRefItems( 'text' ) ) ); 78 | $this->assertEquals( 1, count( $item->getPropertyItems() ) ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Cache/Supplier/Standard.php: -------------------------------------------------------------------------------- 1 | suppliers = $manager->search( $manager->filter(), ['address'] )->col( null, 'supplier.code' )->toArray(); 48 | } 49 | 50 | 51 | /** 52 | * Returns the supplier ID for the given code and type 53 | * 54 | * @param string $code Supplier code 55 | * @param string|null $type Not used 56 | * @return \Aimeos\MShop\Supplier\Item\Iface|null Supplier item or null if not found 57 | */ 58 | public function get( string $code, ?string $type = null ) 59 | { 60 | if( isset( $this->suppliers[$code] ) ) { 61 | return $this->suppliers[$code]; 62 | } 63 | 64 | $manager = \Aimeos\MShop::create( $this->context(), 'supplier' ); 65 | $search = $manager->filter()->add( 'supplier.code', '==', $code ); 66 | 67 | if( $item = $manager->search( $search, ['address'] )->first() ) { 68 | $this->suppliers[$code] = $item; 69 | } 70 | 71 | return $item; 72 | } 73 | 74 | 75 | /** 76 | * Adds the supplier item to the cache 77 | * 78 | * @param \Aimeos\MShop\Common\Item\Iface $item Supplier object 79 | */ 80 | public function set( \Aimeos\MShop\Common\Item\Iface $item ) 81 | { 82 | $this->suppliers[$item->getCode()] = $item; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Subscription/Process/Processor/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 36 | } 37 | 38 | 39 | /** 40 | * Returns the context item 41 | * 42 | * @return \Aimeos\MShop\ContextIface Context object 43 | */ 44 | protected function context() : \Aimeos\MShop\ContextIface 45 | { 46 | return $this->context; 47 | } 48 | 49 | 50 | /** 51 | * Processes the initial subscription 52 | * 53 | * @param \Aimeos\MShop\Subscription\Item\Iface $subscription Subscription item 54 | * @param \Aimeos\MShop\Order\Item\Iface $subscription Order item 55 | */ 56 | public function begin( \Aimeos\MShop\Subscription\Item\Iface $subscription, \Aimeos\MShop\Order\Item\Iface $order ) 57 | { 58 | } 59 | 60 | 61 | /** 62 | * Executed before the subscription renewal 63 | * 64 | * @param \Aimeos\MShop\Subscription\Item\Iface $subscription Subscription item 65 | * @param \Aimeos\MShop\Order\Item\Iface $subscription Order item 66 | */ 67 | public function renewBefore( \Aimeos\MShop\Subscription\Item\Iface $subscription, \Aimeos\MShop\Order\Item\Iface $order ) 68 | { 69 | } 70 | 71 | 72 | /** 73 | * Executed after the subscription renewal 74 | * 75 | * @param \Aimeos\MShop\Subscription\Item\Iface $subscription Subscription item 76 | * @param \Aimeos\MShop\Order\Item\Iface $order Order item 77 | */ 78 | public function renewAfter( \Aimeos\MShop\Subscription\Item\Iface $subscription, \Aimeos\MShop\Order\Item\Iface $order ) 79 | { 80 | } 81 | 82 | 83 | /** 84 | * Processes the end of the subscription 85 | * 86 | * @param \Aimeos\MShop\Subscription\Item\Iface $subscription Subscription item 87 | * @param \Aimeos\MShop\Order\Item\Iface $subscription Order item 88 | */ 89 | public function end( \Aimeos\MShop\Subscription\Item\Iface $subscription, \Aimeos\MShop\Order\Item\Iface $order ) 90 | { 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /templates/controller/jobs/order/email/voucher/html.mjml: -------------------------------------------------------------------------------- 1 | encoder(); 16 | 17 | 18 | $pricetype = 'price:default'; 19 | $pricefmt = $this->translate( 'controller/jobs', $pricetype ); 20 | /// Price format with price value (%1$s) and currency (%2$s) 21 | $priceFormat = $pricefmt !== 'price:default' ? $pricefmt : $this->translate( 'controller/jobs', '%1$s %2$s' ); 22 | 23 | 24 | ?> 25 | 26 | 27 | html( $this->translate( 'controller/jobs', 'Your voucher' ), $enc::TRUST ) ?> 28 | 29 | get( 'css' ) ?> 30 | 31 | 32 | 33 | logo ) ) : ?> 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | html( $this->get( 'intro' ) ) ?> 44 | 45 | 46 | 47 | 48 | 49 | 50 | html( $this->translate( 'controller/jobs', 'Your voucher' ) . ': ' . $this->voucher, $enc::TRUST ) ) ?> 51 | 52 | 53 | translate( 'currency', $this->orderProductItem->getPrice()->getCurrencyId() ) ?> 54 | number( $this->orderProductItem->getPrice()->getValue() + $this->orderProductItem->getPrice()->getRebate(), $this->orderProductItem->getPrice()->getPrecision() ), $priceCurrency ) ?> 55 | html( sprintf( $this->translate( 'controller/jobs', 'The value of your voucher is %1$s', 'The value of your vouchers are %1$s', count( (array) $this->voucher ) ), $value ), $enc::TRUST ) ) ?> 56 | 57 | 58 | 59 | 60 | 61 | 62 | html( $this->translate( 'controller/jobs', 'You can use your vouchers at any time in our online shop' ), $enc::TRUST ) ) ?> 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Processor/Property/Standard.php: -------------------------------------------------------------------------------- 1 | context(), 'product' ); 45 | 46 | $propMap = []; 47 | $items = $product->getPropertyItems( null, false ); 48 | $map = $this->getMappedChunk( $data, $this->getMapping() ); 49 | 50 | foreach( $items as $item ) { 51 | $propMap[$item->getValue()][$item->getType()] = $item; 52 | } 53 | 54 | foreach( $map as $list ) 55 | { 56 | if( ( $value = $this->val( $list, 'product.property.value' ) ) === null ) { 57 | continue; 58 | } 59 | 60 | $type = $this->val( $list, 'product.property.type' ); 61 | $this->addType( 'product/property/type', 'product', $type ); 62 | 63 | if( isset( $propMap[$value][$type] ) ) 64 | { 65 | $item = $propMap[$value][$type]; 66 | $items->remove( $item->getId() ); 67 | } 68 | else 69 | { 70 | $item = $manager->createPropertyItem()->setType( $type ); 71 | } 72 | 73 | $product->addPropertyItem( $item->fromArray( $list ) ); 74 | } 75 | 76 | $product->deletePropertyItems( $items->toArray() ); 77 | 78 | return $this->object()->process( $product, $data ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Customer/Import/Csv/Processor/Property/Standard.php: -------------------------------------------------------------------------------- 1 | context(), 'customer' ); 45 | 46 | $propMap = []; 47 | $items = $customer->getPropertyItems( null, false ); 48 | $map = $this->getMappedChunk( $data, $this->getMapping() ); 49 | 50 | foreach( $items as $item ) { 51 | $propMap[$item->getValue()][$item->getType()] = $item; 52 | } 53 | 54 | foreach( $map as $list ) 55 | { 56 | if( ( $value = $this->val( $list, 'customer.property.value' ) ) === null ) { 57 | continue; 58 | } 59 | 60 | $type = $this->val( $list, 'customer.property.type' ); 61 | $this->addType( 'customer/property/type', 'customer', $type ); 62 | 63 | if( isset( $propMap[$value][$type] ) ) 64 | { 65 | $item = $propMap[$value][$type]; 66 | $items->remove( $item->getId() ); 67 | } 68 | else 69 | { 70 | $item = $manager->createPropertyItem()->setType( $type ); 71 | } 72 | 73 | $customer->addPropertyItem( $item->fromArray( $list ) ); 74 | } 75 | 76 | $customer->deletePropertyItems( $items ); 77 | 78 | return $this->object()->process( $customer, $data ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /templates/controller/jobs/customer/email/account/html.mjml: -------------------------------------------------------------------------------- 1 | encoder(); 9 | 10 | ?> 11 | 12 | 13 | html( $this->translate( 'controller/jobs', 'Your new account' ) ) ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | html( $this->get( 'intro' ) ) ?> 25 | 26 | 27 | html( nl2br( $this->translate( 'controller/jobs', 'An account has been created for you.' ) ) ) ?> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | html( $this->translate( 'controller/jobs', 'Account' ) ) ?>: 36 | 37 | 38 | 39 | 40 | html( $this->get( 'account' ) ) ?> 41 | 42 | 43 | 44 | 45 | 46 | 47 | html( $this->translate( 'controller/jobs', 'Password' ) ) ?>: 48 | 49 | 50 | 51 | 52 | html( $this->get( 'password' ) ?: $this->translate( 'controller/jobs', 'Like entered by you' ) ) ?> 53 | 54 | 55 | 56 | 57 | 58 | 60 | html( $this->translate( 'controller/jobs', 'Login' ) ) ?> 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | html( nl2br( $this->translate( 'controller/jobs', 'If you have any questions, please reply to this e-mail' ) ) ) ?> 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Catalog/Import/Csv/Processor/Base.php: -------------------------------------------------------------------------------- 1 | context = $context; 42 | $this->mapping = $mapping; 43 | $this->object = $object; 44 | } 45 | 46 | 47 | /** 48 | * Stores all types for which no type items exist yet 49 | */ 50 | public function finish() 51 | { 52 | if( $this->object ) { 53 | $this->object->finish(); 54 | } 55 | 56 | $this->saveTypes(); 57 | } 58 | 59 | 60 | /** 61 | * Returns the context item 62 | * 63 | * @return \Aimeos\MShop\ContextIface Context object 64 | */ 65 | protected function context() : \Aimeos\MShop\ContextIface 66 | { 67 | return $this->context; 68 | } 69 | 70 | 71 | /** 72 | * Returns the mapping list 73 | * 74 | * @return array Associative list of field positions in CSV as keys and domain item keys as values 75 | */ 76 | protected function getMapping() : array 77 | { 78 | return $this->mapping; 79 | } 80 | 81 | 82 | /** 83 | * Returns the decorated processor object 84 | * 85 | * @return \Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Iface Processor object 86 | * @throws \Aimeos\Controller\Jobs\Exception If no processor object is available 87 | */ 88 | protected function object() : Iface 89 | { 90 | if( $this->object === null ) { 91 | throw new \Aimeos\Controller\Jobs\Exception( 'No processor object available' ); 92 | } 93 | 94 | return $this->object; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /templates/controller/jobs/product/export/items-partial-media-standard.php: -------------------------------------------------------------------------------- 1 | encoder() 22 | 23 | ?> 24 | 25 | listItems as $listItem ) : ?> 26 | getRefItem() ) : ?> 27 | 30 | xml( $refItem->getType() ) ?>]]> 31 | xml( $refItem->getLanguageId() ) ?>]]> 32 | xml( $refItem->getLabel() ) ?>]]> 33 | xml( $refItem->getUrl() ) ?>]]> 34 | xml( $refItem->getPreview() ) ?>]]> 35 | xml( $refItem->getMimetype() ) ?>]]> 36 | xml( $refItem->getStatus() ) ?>]]> 37 | 38 | getPropertyItems() as $propItem ) : ?> 39 | 40 | xml( $propItem->getType() ) ?>]]> 41 | xml( $propItem->getLanguageId() ) ?>]]> 42 | xml( $propItem->getValue() ) ?>]]> 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Import/Xml/_testfiles/product_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Stock/Import/Csv/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $this->aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Stock\Import\Csv\Standard( $this->context, $this->aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | unset( $this->object ); 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Stock import CSV', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Imports new and updates existing stocks from CSV files'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $fs = $this->context->fs( 'fs-import' ); 53 | $fs->has( 'stock/unittest' ) ?: $fs->mkdir( 'stock/unittest' ); 54 | $fs->writef( 'stock/unittest/stock_1.csv', __DIR__ . '/_testfiles/stock_1.csv' ); 55 | $fs->writef( 'stock/unittest/stock_2.csv', __DIR__ . '/_testfiles/stock_2.csv' ); 56 | 57 | $this->object->run(); 58 | 59 | $map = []; 60 | $manager = \Aimeos\MShop::create( $this->context, 'stock' ); 61 | $prodManager = \Aimeos\MShop::create( $this->context, 'product' ); 62 | 63 | $filter = $prodManager->filter()->add( ['product.code' => ['U:WH', 'U:CF']] ); 64 | $prodIds = $prodManager->search( $filter )->col( 'product.id', 'product.code' )->toArray(); 65 | 66 | $items = $manager->search( $manager->filter()->add( ['stock.productid' => $prodIds] ) ); 67 | $manager->delete( $items->toArray() ); 68 | 69 | foreach( $items as $item ) { 70 | $map[$item->getProductId()] = $item; 71 | } 72 | 73 | $this->assertEquals( 2, count( $map ) ); 74 | 75 | $this->assertEquals( 'test', $map[$prodIds['U:WH']]->getType() ); 76 | $this->assertEquals( 20, $map[$prodIds['U:WH']]->getStockLevel() ); 77 | $this->assertEquals( '2000-01-01 00:00:00', $map[$prodIds['U:WH']]->getDateBack() ); 78 | 79 | $this->assertEquals( 'default', $map[$prodIds['U:CF']]->getType() ); 80 | $this->assertEquals( 5, $map[$prodIds['U:CF']]->getStockLevel() ); 81 | $this->assertEquals( null, $map[$prodIds['U:CF']]->getDateBack() ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Xml/StandardTest.php: -------------------------------------------------------------------------------- 1 | fs( 'fs-import' ); 24 | $fs->has( 'supplier/unittest' ) ?: $fs->mkdir( 'supplier/unittest' ); 25 | $fs->writef( 'supplier/unittest/supplier_1.xml', __DIR__ . '/_testfiles/supplier_1.xml' ); 26 | $fs->writef( 'supplier/unittest/supplier_2.xml', __DIR__ . '/_testfiles/supplier_2.xml' ); 27 | 28 | $fs = $context->fs( 'fs-media' ); 29 | $fs->has( 'path/to' ) ?: $fs->mkdir( 'path/to' ); 30 | $fs->write( 'path/to/file2.jpg', 'test' ); 31 | $fs->write( 'path/to/file.jpg', 'test' ); 32 | 33 | $fs = $context->fs( 'fs-mimeicon' ); 34 | $fs->write( 'unknown.png', 'icon' ); 35 | } 36 | 37 | 38 | protected function setUp() : void 39 | { 40 | \Aimeos\MShop::cache( true ); 41 | 42 | $this->context = \TestHelper::context(); 43 | $this->aimeos = \TestHelper::getAimeos(); 44 | 45 | $this->object = new \Aimeos\Controller\Jobs\Supplier\Import\Xml\Standard( $this->context, $this->aimeos ); 46 | } 47 | 48 | 49 | protected function tearDown() : void 50 | { 51 | \Aimeos\MShop::cache( false ); 52 | unset( $this->object, $this->context, $this->aimeos ); 53 | } 54 | 55 | 56 | public function testGetName() 57 | { 58 | $this->assertEquals( 'Supplier import XML', $this->object->getName() ); 59 | } 60 | 61 | 62 | public function testGetDescription() 63 | { 64 | $text = 'Imports new and updates existing suppliers from XML files'; 65 | $this->assertEquals( $text, $this->object->getDescription() ); 66 | } 67 | 68 | 69 | public function testRun() 70 | { 71 | $this->object->run(); 72 | 73 | $manager = \Aimeos\MShop::create( $this->context, 'supplier' ); 74 | $item = $manager->find( 'unittest-xml', ['media', 'text', 'product', 'supplier/address'] ); 75 | $manager->delete( $item->getId() ); 76 | 77 | $this->assertEquals( 'Test supplier', $item->getLabel() ); 78 | $this->assertEquals( 1, count( $item->getRefItems( 'product' ) ) ); 79 | $this->assertEquals( 1, count( $item->getRefItems( 'media' ) ) ); 80 | $this->assertEquals( 1, count( $item->getRefItems( 'text' ) ) ); 81 | $this->assertEquals( 1, count( $item->getAddressItems() ) ); 82 | $this->assertEquals( 'ms', $item->getAddressItems()->first()->getSalutation() ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Decorator/Base.php: -------------------------------------------------------------------------------- 1 | controller = $controller; 40 | } 41 | 42 | 43 | /** 44 | * Passes unknown methods to wrapped objects. 45 | * 46 | * @param string $name Name of the method 47 | * @param array $param List of method parameter 48 | * @return mixed Returns the value of the called method 49 | * @throws \Aimeos\Controller\Jobs\Exception If method call failed 50 | */ 51 | public function __call( string $name, array $param ) 52 | { 53 | return call_user_func_array( array( $this->controller, $name ), $param ); 54 | } 55 | 56 | 57 | /** 58 | * Returns the localized name of the job. 59 | * 60 | * @return string Name of the job 61 | */ 62 | public function getName() : string 63 | { 64 | return $this->controller->getName(); 65 | } 66 | 67 | 68 | /** 69 | * Returns the localized description of the job. 70 | * 71 | * @return string Description of the job 72 | */ 73 | public function getDescription() : string 74 | { 75 | return $this->controller->getDescription(); 76 | } 77 | 78 | 79 | /** 80 | * Executes the job. 81 | * 82 | * @throws \Aimeos\Controller\Jobs\Exception If an error occurs 83 | */ 84 | public function run() 85 | { 86 | $this->controller->run(); 87 | } 88 | 89 | 90 | /** 91 | * Returns the job controller 92 | * 93 | * @return \Aimeos\Controller\Jobs\Iface Job controller object 94 | */ 95 | protected function getController() : \Aimeos\Controller\Jobs\Iface 96 | { 97 | return $this->controller; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Customer/Import/Xml/StandardTest.php: -------------------------------------------------------------------------------- 1 | fs( 'fs-import' ); 24 | $fs->has( 'customer/unittest' ) ?: $fs->mkdir( 'customer/unittest' ); 25 | $fs->writef( 'customer/unittest/customer_1.xml', __DIR__ . '/_testfiles/customer_1.xml' ); 26 | $fs->writef( 'customer/unittest/customer_2.xml', __DIR__ . '/_testfiles/customer_2.xml' ); 27 | 28 | $fs = $context->fs( 'fs-media' ); 29 | $fs->has( 'path/to' ) ?: $fs->mkdir( 'path/to' ); 30 | $fs->write( 'path/to/file2.jpg', 'test' ); 31 | $fs->write( 'path/to/file.jpg', 'test' ); 32 | 33 | $fs = $context->fs( 'fs-mimeicon' ); 34 | $fs->write( 'unknown.png', 'icon' ); 35 | } 36 | 37 | 38 | protected function setUp() : void 39 | { 40 | $this->context = \TestHelper::context(); 41 | $this->aimeos = \TestHelper::getAimeos(); 42 | 43 | $this->object = new \Aimeos\Controller\Jobs\Customer\Import\Xml\Standard( $this->context, $this->aimeos ); 44 | } 45 | 46 | 47 | protected function tearDown() : void 48 | { 49 | unset( $this->object, $this->context, $this->aimeos ); 50 | } 51 | 52 | 53 | public function testGetName() 54 | { 55 | $this->assertEquals( 'Customer import XML', $this->object->getName() ); 56 | } 57 | 58 | 59 | public function testGetDescription() 60 | { 61 | $text = 'Imports new and updates existing customers from XML files'; 62 | $this->assertEquals( $text, $this->object->getDescription() ); 63 | } 64 | 65 | 66 | public function testRun() 67 | { 68 | $this->object->run(); 69 | 70 | $manager = \Aimeos\MShop::create( $this->context, 'customer' ); 71 | $item = $manager->find( 'me@example.com', ['customer/address', 'customer/property', 'media', 'text'] ); 72 | $manager->delete( $item->getId() ); 73 | 74 | $this->assertEquals( 'Test user', $item->getLabel() ); 75 | $this->assertEquals( 1, count( $item->getPropertyItems() ) ); 76 | $this->assertEquals( 1, count( $item->getRefItems( 'text' ) ) ); 77 | $this->assertEquals( 1, count( $item->getRefItems( 'media' ) ) ); 78 | $this->assertEquals( 'ms', $item->getPaymentAddress()->getSalutation() ); 79 | $this->assertEquals( 'Example street', $item->getPaymentAddress()->getAddress1() ); 80 | $this->assertEquals( 'ms', $item->getAddressItems()->first()->getSalutation() ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Xml/_testfiles/supplier_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 |
53 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Supplier/Import/Xml/_testfiles/supplier_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 |
53 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Cache/Attribute/Standard.php: -------------------------------------------------------------------------------- 1 | search( $manager->filter() ); 48 | 49 | foreach( $result as $id => $item ) { 50 | $this->attributes[$item->getCode()][$item->getType()] = $item; 51 | } 52 | } 53 | 54 | 55 | /** 56 | * Returns the attribute item for the given code and type 57 | * 58 | * @param string $code Attribute code 59 | * @param string|null $type Attribute type 60 | * @return \Aimeos\MShop\Attribute\Item\Iface|null Attribute object or null if not found 61 | */ 62 | public function get( string $code, ?string $type = null ) 63 | { 64 | if( isset( $this->attributes[$code][$type] ) ) { 65 | return $this->attributes[$code][$type]; 66 | } 67 | 68 | $manager = \Aimeos\MShop::create( $this->context(), 'attribute' ); 69 | $search = $manager->filter()->add( ['attribute.code' => $code, 'attribute.type' => $type] ); 70 | 71 | if( $item = $manager->search( $search )->first() ) { 72 | $this->attributes[$code][$type] = $item; 73 | } 74 | 75 | return $item; 76 | } 77 | 78 | 79 | /** 80 | * Adds the attribute item to the cache 81 | * 82 | * @param \Aimeos\MShop\Common\Item\Iface $item Attribute object 83 | */ 84 | public function set( \Aimeos\MShop\Common\Item\Iface $item ) 85 | { 86 | $this->attributes[$item->getCode()][$item->getType()] = $item; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Product/Export/Sitemap/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $this->aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Product\Export\Sitemap\Standard( $this->context, $this->aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | $this->object = null; 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Product site map', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Creates a product site map for search engines'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $this->context->config()->set( 'controller/jobs/product/export/sitemap/max-items', 5 ); 53 | $this->context->config()->set( 'resource/fs/baseurl', 'https://www.yourshop.com/' ); 54 | 55 | $this->object->run(); 56 | 57 | $ds = DIRECTORY_SEPARATOR; 58 | $this->assertFileExists( 'tmp' . $ds . 'unittest-sitemap-1.xml' ); 59 | $this->assertFileExists( 'tmp' . $ds . 'unittest-sitemap-2.xml' ); 60 | $this->assertFileExists( 'tmp' . $ds . 'unittest-sitemap-index.xml' ); 61 | 62 | $file1 = file_get_contents( 'tmp' . $ds . 'unittest-sitemap-1.xml' ); 63 | $file2 = file_get_contents( 'tmp' . $ds . 'unittest-sitemap-2.xml' ); 64 | $index = file_get_contents( 'tmp' . $ds . 'unittest-sitemap-index.xml' ); 65 | 66 | unlink( 'tmp' . $ds . 'unittest-sitemap-1.xml' ); 67 | unlink( 'tmp' . $ds . 'unittest-sitemap-2.xml' ); 68 | unlink( 'tmp' . $ds . 'unittest-sitemap-index.xml' ); 69 | 70 | $this->assertStringContainsString( 'cafe_noire_expresso', $file2 ); 71 | $this->assertStringContainsString( 'unittest-bundle', $file2 ); 72 | 73 | $this->assertStringContainsString( 'https://www.yourshop.com/unittest-sitemap-1.xml', $index ); 74 | $this->assertStringContainsString( 'https://www.yourshop.com/unittest-sitemap-2.xml', $index ); 75 | } 76 | 77 | 78 | public function testRunEmptyBaseurl() 79 | { 80 | $this->context->config()->set( 'resource/fs/baseurl', '' ); 81 | 82 | $this->expectException( '\\Aimeos\\Controller\\Jobs\\Exception' ); 83 | $this->object->run(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Order/Status/Csv/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $this->aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Order\Status\Csv\Standard( $this->context, $this->aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( true ); 33 | unset( $this->object, $this->context, $this->aimeos ); 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Order status import CSV', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $this->assertEquals( 'Status import for orders from CSV file', $this->object->getDescription() ); 46 | } 47 | 48 | 49 | public function testRun() 50 | { 51 | $dir = dirname( __DIR__, 5 ) . '/tmp/import/orderstatus'; 52 | file_exists( $dir ) ?: mkdir( $dir ); 53 | copy( __DIR__ . '/_test/status.csv', $dir . '/status.csv' ); 54 | 55 | 56 | $this->context->config()->set( 'controller/jobs/order/status/csv/separator', ';' ); 57 | $this->context->config()->set( 'controller/jobs/order/status/csv/skip', 1 ); 58 | 59 | 60 | $orderStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Order\\Manager\\Standard' ) 61 | ->setConstructorArgs( [$this->context] ) 62 | ->onlyMethods( ['save', 'search'] ) 63 | ->getMock(); 64 | 65 | $oProdStub = $this->getMockBuilder( '\\Aimeos\\MShop\\Order\\Manager\\Product\\Standard' ) 66 | ->setConstructorArgs( [$this->context] ) 67 | ->onlyMethods( ['save', 'search'] ) 68 | ->getMock(); 69 | 70 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Order\\Manager\\Standard', $orderStub ); 71 | \Aimeos\MShop::inject( '\\Aimeos\\MShop\\Order\\Manager\\Product\\Standard', $oProdStub ); 72 | 73 | 74 | $orderStub->expects( $this->once() )->method( 'search' ) 75 | ->willReturn( map( [$orderStub->create()->setId( 1 )] ) ); 76 | 77 | $oProdStub->expects( $this->once() )->method( 'search' ) 78 | ->willReturn( map( [$oProdStub->create()->setId( 2 )] ) ); 79 | 80 | $orderStub->expects( $this->once() )->method( 'save' ); 81 | $oProdStub->expects( $this->once() )->method( 'save' ); 82 | 83 | 84 | $object = new \Aimeos\Controller\Jobs\Order\Status\Csv\Standard( $this->context, $this->aimeos ); 85 | $object->run(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Import/Xml/StandardTest.php: -------------------------------------------------------------------------------- 1 | fs( 'fs-import' ); 24 | $fs->has( 'catalog/unittest' ) ?: $fs->mkdir( 'catalog/unittest' ); 25 | $fs->writef( 'catalog/unittest/catalog_1.xml', __DIR__ . '/_testfiles/catalog_1.xml' ); 26 | $fs->writef( 'catalog/unittest/catalog_2.xml', __DIR__ . '/_testfiles/catalog_2.xml' ); 27 | 28 | $fs = $context->fs( 'fs-media' ); 29 | $fs->has( 'path/to' ) ?: $fs->mkdir( 'path/to' ); 30 | $fs->write( 'path/to/file2.jpg', 'test' ); 31 | $fs->write( 'path/to/file.jpg', 'test' ); 32 | 33 | $fs = $context->fs( 'fs-mimeicon' ); 34 | $fs->write( 'unknown.png', 'icon' ); 35 | } 36 | 37 | 38 | protected function setUp() : void 39 | { 40 | \Aimeos\MShop::cache( true ); 41 | 42 | $this->context = \TestHelper::context(); 43 | $this->aimeos = \TestHelper::getAimeos(); 44 | 45 | $this->object = new \Aimeos\Controller\Jobs\Catalog\Import\Xml\Standard( $this->context, $this->aimeos ); 46 | } 47 | 48 | 49 | protected function tearDown() : void 50 | { 51 | \Aimeos\MShop::cache( false ); 52 | unset( $this->object, $this->context, $this->aimeos ); 53 | } 54 | 55 | 56 | public function testGetName() 57 | { 58 | $this->assertEquals( 'Catalog import XML', $this->object->getName() ); 59 | } 60 | 61 | 62 | public function testGetDescription() 63 | { 64 | $text = 'Imports new and updates existing categories from XML files'; 65 | $this->assertEquals( $text, $this->object->getDescription() ); 66 | } 67 | 68 | 69 | public function testRun() 70 | { 71 | $this->object->run(); 72 | 73 | $manager = \Aimeos\MShop::create( $this->context, 'catalog' ); 74 | $tree = $manager->getTree( $manager->find( 'unittest-xml' )->getId(), ['media', 'product', 'text'] ); 75 | $manager->delete( $tree->getId() ); 76 | 77 | $this->assertEquals( 'Test catalog', $tree->getLabel() ); 78 | $this->assertEquals( ['css' => 'new'], $tree->getConfig() ); 79 | $this->assertEquals( 2, count( $tree->getChildren() ) ); 80 | $this->assertEquals( 1, count( $tree->getRefItems( 'text', null, null, false ) ) ); 81 | $this->assertEquals( 'Test sub-category 3', $tree->getChild( 0 )->getLabel() ); 82 | $this->assertEquals( 2, count( $tree->getChild( 0 )->getRefItems( 'product' ) ) ); 83 | $this->assertEquals( 'Test sub-category 3-1', $tree->getChild( 0 )->getChild( 0 )->getLabel() ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Product/Import/Csv/Processor/Stock/Standard.php: -------------------------------------------------------------------------------- 1 | context(), 'stock' ); 45 | $manager->begin(); 46 | 47 | try 48 | { 49 | $stock = 0; 50 | $map = $this->getMappedChunk( $data, $this->getMapping() ); 51 | $items = $manager->search( $manager->filter()->add( ['stock.productid' => $product->getId()] ) ); 52 | $items = $items->col( null, 'stock.type' ); 53 | 54 | foreach( $map as $pos => $list ) 55 | { 56 | if( !array_key_exists( 'stock.stocklevel', $list ) ) { 57 | continue; 58 | } 59 | 60 | $list['stock.productid'] = $product->getId(); 61 | $list['stock.type'] = $this->val( $list, 'stock.type', 'default' ); 62 | 63 | $this->addType( 'stock/type', 'stock', $list['stock.type'] ); 64 | 65 | $item = $items->pull( $list['stock.type'] ) ?: $manager->create(); 66 | $manager->save( $item->fromArray( $list ), false ); 67 | 68 | if( $item->getStockLevel() === null || $item->getStockLevel() > 0 ) { 69 | $stock = 1; 70 | } 71 | } 72 | 73 | $manager->delete( $items ); 74 | $product->setInStock( $stock ); 75 | 76 | $data = $this->object()->process( $product, $data ); 77 | 78 | $manager->commit(); 79 | } 80 | catch( \Exception $e ) 81 | { 82 | $manager->rollback(); 83 | throw $e; 84 | } 85 | 86 | return $data; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Processor/Property/Standard.php: -------------------------------------------------------------------------------- 1 | getResourceType(); 47 | $manager = \Aimeos\MShop::create( $this->context(), $resource ); 48 | $propItems = $item->getPropertyItems( null, false ); 49 | $map = []; 50 | 51 | foreach( $propItems as $propItem ) { 52 | $map[$propItem->getType()][$propItem->getLanguageId()][$propItem->getValue()] = $propItem->getId(); 53 | } 54 | 55 | foreach( $node->childNodes as $propNode ) 56 | { 57 | if( $propNode->nodeName !== 'propertyitem' ) { 58 | continue; 59 | } 60 | 61 | $list = []; 62 | 63 | foreach( $propNode->childNodes as $tagNode ) { 64 | $list[$tagNode->nodeName] = \Aimeos\Base\Str::decode( $tagNode->nodeValue ); 65 | } 66 | 67 | $propItem = $manager->createPropertyItem()->fromArray( $list ); 68 | 69 | if( isset( $map[$propItem->getType()][$propItem->getLanguageId()][$propItem->getValue()] ) ) { 70 | $propItems->remove( $map[$propItem->getType()][$propItem->getLanguageId()][$propItem->getValue()] ); 71 | } else { 72 | $item->addPropertyItem( $propItem ); 73 | } 74 | 75 | $this->addType( $resource . '/property/type', 'product', $propItem->getType() ); 76 | } 77 | 78 | return $item->deletePropertyItems( $propItems->toArray() ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Catalog/Export/Sitemap/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 24 | $this->aimeos = \TestHelper::getAimeos(); 25 | 26 | $this->object = new \Aimeos\Controller\Jobs\Catalog\Export\Sitemap\Standard( $this->context, $this->aimeos ); 27 | } 28 | 29 | 30 | protected function tearDown() : void 31 | { 32 | \Aimeos\MShop::cache( false ); 33 | $this->object = null; 34 | } 35 | 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals( 'Catalog site map', $this->object->getName() ); 40 | } 41 | 42 | 43 | public function testGetDescription() 44 | { 45 | $text = 'Creates a catalog site map for search engines'; 46 | $this->assertEquals( $text, $this->object->getDescription() ); 47 | } 48 | 49 | 50 | public function testRun() 51 | { 52 | $this->context->config()->set( 'controller/jobs/catalog/export/sitemap/max-items', 5 ); 53 | $this->context->config()->set( 'resource/fs/baseurl', 'https://www.yourshop.com/' ); 54 | 55 | $this->object->run(); 56 | 57 | $ds = DIRECTORY_SEPARATOR; 58 | $this->assertFileExists( 'tmp' . $ds . 'aimeos-catalog-sitemap-1.xml' ); 59 | $this->assertFileExists( 'tmp' . $ds . 'aimeos-catalog-sitemap-2.xml' ); 60 | $this->assertFileExists( 'tmp' . $ds . 'aimeos-catalog-sitemap-index.xml' ); 61 | 62 | $file1 = file_get_contents( 'tmp' . $ds . 'aimeos-catalog-sitemap-1.xml' ); 63 | $file2 = file_get_contents( 'tmp' . $ds . 'aimeos-catalog-sitemap-2.xml' ); 64 | $index = file_get_contents( 'tmp' . $ds . 'aimeos-catalog-sitemap-index.xml' ); 65 | 66 | unlink( 'tmp' . $ds . 'aimeos-catalog-sitemap-1.xml' ); 67 | unlink( 'tmp' . $ds . 'aimeos-catalog-sitemap-2.xml' ); 68 | unlink( 'tmp' . $ds . 'aimeos-catalog-sitemap-index.xml' ); 69 | 70 | $this->assertStringContainsString( 'kaffee', $file1 ); 71 | $this->assertStringContainsString( 'misc', $file1 ); 72 | $this->assertStringContainsString( 'groups', $file2 ); 73 | 74 | $this->assertStringContainsString( 'https://www.yourshop.com/aimeos-catalog-sitemap-1.xml', $index ); 75 | $this->assertStringContainsString( 'https://www.yourshop.com/aimeos-catalog-sitemap-2.xml', $index ); 76 | } 77 | 78 | 79 | public function testRunEmptyBaseurl() 80 | { 81 | $this->context->config()->set( 'resource/fs/baseurl', '' ); 82 | 83 | $this->expectException( '\\Aimeos\\Controller\\Jobs\\Exception' ); 84 | $this->object->run(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Import/Xml/Traits.php: -------------------------------------------------------------------------------- 1 | processors[$type] ) ) { 42 | $this->processors[$type] = $this->createProcessor( $type ); 43 | } 44 | 45 | return $this->processors[$type]; 46 | } 47 | 48 | 49 | /** 50 | * Returns the processor objects which have been used up to now 51 | * 52 | * @return \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Iface[] List of processor objects 53 | */ 54 | protected function getProcessors() : array 55 | { 56 | return $this->processors; 57 | } 58 | 59 | 60 | /** 61 | * Creates a new processor object of the given type 62 | * 63 | * @param string $type Type of the processor 64 | * @return \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Iface Processor object 65 | * @throws \LogicException If class can't be instantiated 66 | */ 67 | protected function createProcessor( string $type ) : \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Iface 68 | { 69 | $context = $this->context(); 70 | $config = $context->config(); 71 | $parts = explode( '/', $type ); 72 | 73 | foreach( $parts as $part ) 74 | { 75 | if( ctype_alnum( $part ) === false ) { 76 | throw new \LogicException( sprintf( 'Invalid characters in processor type "%1$s"', $type ), 400 ); 77 | } 78 | } 79 | 80 | $name = $config->get( 'controller/jobs/common/import/xml/processor/' . $type . '/name', 'Standard' ); 81 | 82 | if( ctype_alnum( $name ) === false ) { 83 | throw new \LogicException( sprintf( 'Invalid characters in processor name "%1$s"', $name ), 400 ); 84 | } 85 | 86 | $segment = str_replace( '/', '\\', ucwords( $type, '/' ) ) . '\\' . $name; 87 | $classname = '\\Aimeos\\Controller\\Jobs\\Common\\Import\\Xml\\Processor\\' . $segment; 88 | $interface = \Aimeos\Controller\Jobs\Common\Import\Xml\Processor\Iface::class; 89 | 90 | return \Aimeos\Utils::create( $classname, [$context], $interface ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/Controller/Jobs/Common/Customer/Import/Xml/Processor/Group/StandardTest.php: -------------------------------------------------------------------------------- 1 | context = \TestHelper::context(); 21 | $this->object = new \Aimeos\Controller\Jobs\Common\Customer\Import\Xml\Processor\Group\Standard( $this->context ); 22 | } 23 | 24 | 25 | protected function tearDown() : void 26 | { 27 | unset( $this->object, $this->context ); 28 | } 29 | 30 | 31 | public function testProcess() 32 | { 33 | $dom = new \DOMDocument(); 34 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create(); 35 | $grpId = \Aimeos\MShop::create( $this->context, 'group' )->find( 'unitgroup' )->getId(); 36 | 37 | $dom->loadXML( ' 38 | 39 | 40 | ' ); 41 | 42 | $customer = $this->object->process( $customer, $dom->firstChild ); 43 | 44 | $this->assertEquals( 1, count( $customer->getGroups() ) ); 45 | $this->assertEquals( $grpId, current( $customer->getGroups() ) ); 46 | } 47 | 48 | 49 | public function testProcessUpdate() 50 | { 51 | $dom = new \DOMDocument(); 52 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create(); 53 | $grpId = \Aimeos\MShop::create( $this->context, 'group' )->find( 'unitgroup2' )->getId(); 54 | 55 | $dom->loadXML( ' 56 | 57 | 58 | ' ); 59 | 60 | $customer = $this->object->process( $customer, $dom->firstChild ); 61 | 62 | $dom->loadXML( ' 63 | 64 | 65 | ' ); 66 | 67 | $customer = $this->object->process( $customer, $dom->firstChild ); 68 | 69 | $this->assertEquals( 1, count( $customer->getGroups() ) ); 70 | $this->assertEquals( $grpId, current( $customer->getGroups() ) ); 71 | } 72 | 73 | 74 | public function testProcessDelete() 75 | { 76 | $dom = new \DOMDocument(); 77 | $customer = \Aimeos\MShop::create( $this->context, 'customer' )->create(); 78 | 79 | $dom->loadXML( ' 80 | 81 | 82 | ' ); 83 | 84 | $customer = $this->object->process( $customer, $dom->firstChild ); 85 | 86 | $dom->loadXML( ' 87 | 88 | ' ); 89 | 90 | $customer = $this->object->process( $customer, $dom->firstChild ); 91 | 92 | $this->assertEquals( 0, count( $customer->getGroups() ) ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Controller/Jobs/Common/Customer/Import/Xml/Processor/Group/Standard.php: -------------------------------------------------------------------------------- 1 | groupManager = \Aimeos\MShop::create( $context, 'group' ); 48 | $search = $this->groupManager->filter(); 49 | $start = 0; 50 | 51 | do 52 | { 53 | $items = $this->groupManager->search( $search->slice( $start, 100 ) ); 54 | 55 | foreach( $items as $item ) { 56 | $this->map[$item->getCode()] = $item->getId(); 57 | } 58 | 59 | $count = count( $items ); 60 | $start += $count; 61 | unset( $items ); 62 | } 63 | while( $count === $search->getLimit() ); 64 | } 65 | 66 | 67 | /** 68 | * Updates the given item using the data from the DOM node 69 | * 70 | * @param \Aimeos\MShop\Common\Item\Iface $item Item which should be updated 71 | * @param \DOMNode $node XML document node containing a list of nodes to process 72 | * @return \Aimeos\MShop\Common\Item\Iface Updated item 73 | */ 74 | public function process( \Aimeos\MShop\Common\Item\Iface $item, \DOMNode $node ) : \Aimeos\MShop\Common\Item\Iface 75 | { 76 | \Aimeos\Utils::implements( $item, \Aimeos\MShop\Customer\Item\Iface::class ); 77 | 78 | $ids = []; 79 | 80 | foreach( $node->childNodes as $node ) 81 | { 82 | if( $node->nodeName === 'groupitem' && ( $refattr = $node->attributes->getNamedItem( 'ref' ) ) !== null ) 83 | { 84 | $code = $refattr->nodeValue; 85 | 86 | if( !isset( $this->map[$code] ) ) { 87 | $this->map[$code] = $this->groupManager->find( $code )->getId(); 88 | } 89 | 90 | $ids[] = $this->map[$code]; 91 | } 92 | } 93 | 94 | return $item->setGroups( $ids ); 95 | } 96 | } 97 | --------------------------------------------------------------------------------