├── var ├── cache │ └── .gitignore └── data │ └── .gitignore ├── .env.local ├── Resources ├── mockup │ ├── Product │ │ ├── list.json │ │ ├── item.json │ │ ├── pictures.json │ │ ├── day_visits.json │ │ └── MLB803848501.json │ ├── Order │ │ ├── Status │ │ │ ├── Processing.json │ │ │ └── Shipped.json │ │ ├── notfound.json │ │ └── item.json │ └── Message │ │ ├── creationRequest.json │ │ ├── creationResponse.json │ │ ├── item.json │ │ └── list.json ├── qualityAssurance │ └── .gitignore ├── sample │ └── newMessage.yaml └── schema │ ├── product.yaml │ └── order.yaml ├── .env ├── MercadoLivreSdk.code-workspace ├── config ├── phpstan.neon ├── cli-config.php └── bootstrap.php ├── docs ├── _config.yml ├── index.md └── _layouts │ └── default.html ├── .gitignore ├── .php_cs.dist ├── Makefile ├── src ├── Entity │ ├── Message │ │ ├── From.php │ │ ├── To.php │ │ ├── map │ │ │ └── restful.map.php │ │ ├── UserCollection.php │ │ ├── MessageCollection.php │ │ ├── Text.php │ │ ├── User.php │ │ ├── Message.php │ │ └── Manager.php │ ├── User │ │ ├── map │ │ │ └── restful.map.php │ │ └── Manager.php │ ├── Product │ │ ├── Exceptions │ │ │ ├── AdWithoutDescription.php │ │ │ ├── AdHasVariationException.php │ │ │ ├── AdFreezedByDealException.php │ │ │ └── AdWithoutVariationException.php │ │ ├── Pictures │ │ │ ├── Collection.php │ │ │ └── Picture.php │ │ ├── ProductCollection.php │ │ ├── map │ │ │ ├── translate.foreign.map.php │ │ │ └── translate.native.map.php │ │ ├── Product.php │ │ └── Translator.php │ ├── Order │ │ ├── Buyer │ │ │ ├── Phone.php │ │ │ ├── AlternativePhone.php │ │ │ ├── BillingInfo.php │ │ │ └── Buyer.php │ │ ├── Seller │ │ │ ├── Phone.php │ │ │ ├── AlternativePhone.php │ │ │ └── Seller.php │ │ ├── Shipping │ │ │ ├── City.php │ │ │ ├── State.php │ │ │ ├── Country.php │ │ │ ├── Speed.php │ │ │ ├── ShippingItems │ │ │ │ ├── Collection.php │ │ │ │ └── Item.php │ │ │ ├── EstimatedDelivery.php │ │ │ ├── ShippingOption.php │ │ │ ├── ReceiverAddress.php │ │ │ └── Shipping.php │ │ ├── map │ │ │ ├── status.map.php │ │ │ ├── schema.map.php │ │ │ ├── translate.foreign.map.php │ │ │ ├── restful.map.php │ │ │ └── translate.native.map.php │ │ ├── Decorator │ │ │ ├── DecoratorInterface.php │ │ │ ├── Status │ │ │ │ ├── Processing.php │ │ │ │ └── Shipped.php │ │ │ └── AbstractDecorator.php │ │ ├── Payments │ │ │ ├── Collector.php │ │ │ ├── Collection.php │ │ │ ├── AtmTransferReference.php │ │ │ └── Payment.php │ │ ├── StatusDetail.php │ │ ├── OrderCollection.php │ │ ├── Order.php │ │ ├── OrderItems │ │ │ ├── Collection.php │ │ │ └── Item.php │ │ └── Translator.php │ ├── AbstractLocation.php │ ├── AbstractPhone.php │ ├── GenericManager.php │ ├── AbstractMetadata.php │ └── AbstractManager.php ├── Client │ ├── Ml.php │ └── Client.php ├── Console │ ├── Command │ │ ├── Auth │ │ │ ├── ChecklistCommand.php │ │ │ ├── TokenCommand.php │ │ │ └── RefreshCommand.php │ │ ├── AbstractCommand.php │ │ ├── Schema │ │ │ ├── OrderCommand.php │ │ │ └── ProductCommand.php │ │ ├── Catalog │ │ │ └── Product │ │ │ │ ├── ViewCommand.php │ │ │ │ └── ListCommand.php │ │ ├── User │ │ │ └── MeCommand.php │ │ ├── Message │ │ │ ├── CreateCommand.php │ │ │ └── ListCommand.php │ │ └── Trading │ │ │ └── Order │ │ │ └── ListCommand.php │ └── Application.php └── Factory.php ├── docker-compose.yaml ├── .editorconfig ├── .rmt.yml ├── bin └── mercadolivre-sdk ├── .travis.yml ├── .github └── workflows │ └── php.yml ├── tests ├── Entity │ ├── Order │ │ ├── Decorator │ │ │ ├── Status │ │ │ │ ├── ShippedTest.php │ │ │ │ └── ProcessingTest.php │ │ │ └── AbstractDecoratorTestCase.php │ │ ├── StatusDetailTest.php │ │ ├── OrderItems │ │ │ ├── ItemTest.php │ │ │ └── CollectionTest.php │ │ ├── OrderCollectionTest.php │ │ ├── Payments │ │ │ ├── CollectorTest.php │ │ │ └── AtmTransferReferenceTest.php │ │ ├── TranslatorTest.php │ │ ├── Buyer │ │ │ └── BillingInfoTest.php │ │ └── Shipping │ │ │ ├── SpeedTest.php │ │ │ └── EstimatedDeliveryTest.php │ ├── Message │ │ ├── MessageTest.php │ │ └── ManagerTest.php │ └── Product │ │ └── TranslatorTest.php ├── Client │ ├── ClientTest.php │ └── MlTest.php ├── Console │ └── ApplicationTest.php ├── FactoryTest.php ├── Bootstrap.php └── TestCaseAbstract.php ├── phpcs.xml ├── phpcs.xml.dist ├── LICENSE ├── composer.json ├── phpunit.xml.dist └── README.md /var/cache/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /var/data/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.env.local: -------------------------------------------------------------------------------- 1 | dbhost='mariadb' 2 | -------------------------------------------------------------------------------- /Resources/mockup/Product/list.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Resources/qualityAssurance/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Resources/mockup/Product/item.json: -------------------------------------------------------------------------------- 1 | MLB803848501.json -------------------------------------------------------------------------------- /Resources/mockup/Order/Status/Processing.json: -------------------------------------------------------------------------------- 1 | {"status":"handling"} 2 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | dbhost='127.0.0.1' 2 | CONTAINER_ORCHESTRATION_TAG_VERSION=v2.1.0 3 | -------------------------------------------------------------------------------- /Resources/mockup/Order/Status/Shipped.json: -------------------------------------------------------------------------------- 1 | {"tracking_number":"TR1234567891","service_id":22} 2 | -------------------------------------------------------------------------------- /MercadoLivreSdk.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /config/phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | fileExtensions: 3 | - php 4 | bootstrap: %currentWorkingDirectory%/config/bootstrap.php 5 | -------------------------------------------------------------------------------- /Resources/mockup/Order/notfound.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": "Order not found.", 3 | "error": "order_not_found", 4 | "status": 404, 5 | "cause": null 6 | } 7 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | highlighter: rouge 2 | markdown: kramdown 3 | kramdown: 4 | input: GFM 5 | auto_ids: true 6 | syntax_highlighter: rouge 7 | plugins: 8 | - jemoji 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /vendor/ 3 | /var/ 4 | /.env.local 5 | Resources/logs/* 6 | Resources/qualityAssurance/* 7 | *.phar 8 | *.lock 9 | *.cache 10 | phpunit.xml 11 | Resources/mockup/*/*-private.json 12 | -------------------------------------------------------------------------------- /Resources/sample/newMessage.yaml: -------------------------------------------------------------------------------- 1 | from: 2 | user_id: '123456789' 3 | to: 4 | - user_id: '123456780' 5 | site_id: MLB 6 | resource: orders 7 | resource_id: '1234567871' 8 | subject: Test Item subject 9 | text: 10 | plain: Ejemplo de texto 11 | -------------------------------------------------------------------------------- /Resources/mockup/Product/pictures.json: -------------------------------------------------------------------------------- 1 | { 2 | "pictures": [ 3 | {"id": "946905-MLB25122284495_102016"}, 4 | {"source": "http://static.sepha.com.br/prd/1200/1214/1214_3_desc_30.jpg"}, 5 | {"source": "http://static.sepha.com.br/prd/1200/1214/1214_2_desc_20.jpg"} 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.php_cs.dist: -------------------------------------------------------------------------------- 1 | 'gpupo/mercadolivre-sdk', 7 | 'author' => 'Gilmar Pupo ', 8 | 'url' => 'https://opensource.gpupo.com/', 9 | ]; 10 | 11 | return (new CsConfigurator(__DIR__))->getConfig($packageInfo); 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This file has settings for the Make of this project. 2 | # Targets must exist in the bin/make-file/targets/ directory. 3 | 4 | .SILENT: 5 | CURRENT_DIR := $(shell pwd) 6 | 7 | install: 8 | COMPOSER_MEMORY_LIMIT=9G composer install --prefer-dist --no-scripts 9 | update: 10 | test -f composer.lock && rm composer.lock 11 | COMPOSER_MEMORY_LIMIT=9G composer update --prefer-dist --no-scripts -------------------------------------------------------------------------------- /Resources/mockup/Message/creationRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "from": { 3 | "user_id": "123456789" 4 | }, 5 | "to": [ 6 | { 7 | "user_id": "123456780", 8 | "site_id": "MLB", 9 | "resource": "orders", 10 | "resource_id": "1234567871" 11 | } 12 | ], 13 | "subject": "Test Item subject", 14 | "text": { 15 | "plain": "Ejemplo de texto" 16 | }, 17 | "attachments": [ 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/Entity/Message/From.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | class From extends User 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/Entity/Message/To.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | class To extends UserCollection 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/Entity/User/map/restful.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | return [ 12 | 'me' => [ 13 | 'GET', 14 | '/users/me?', 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | services: 3 | php-fpm: 4 | image: gpupo/container-orchestration:php-dev-${CONTAINER_ORCHESTRATION_TAG_VERSION} 5 | volumes: 6 | - $PWD/:/var/www/app 7 | mariadb: 8 | image: mariadb 9 | restart: always 10 | expose: 11 | - 3306 12 | environment: 13 | MYSQL_ROOT_PASSWORD: mas7er 14 | MYSQL_USER: app_db_user 15 | MYSQL_PASSWORD: app8as3 16 | MYSQL_DATABASE: app 17 | -------------------------------------------------------------------------------- /src/Entity/Product/Exceptions/AdWithoutDescription.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Exceptions; 12 | 13 | class AdWithoutDescription extends \Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/Entity/Product/Exceptions/AdHasVariationException.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Exceptions; 12 | 13 | class AdHasVariationException extends \Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /Resources/schema/product.yaml: -------------------------------------------------------------------------------- 1 | id: string 2 | title: string 3 | description: 4 | - 5 | plain_text: string 6 | category_id: string 7 | price: number 8 | currency_id: string 9 | buying_mode: string 10 | listing_type_id: string 11 | condition: string 12 | pictures: 13 | - 14 | id: string 15 | url: string 16 | secure_url: string 17 | size: string 18 | max_size: string 19 | quality: string 20 | available_quantity: number 21 | shipping: array 22 | official_store_id: number 23 | status: string 24 | -------------------------------------------------------------------------------- /src/Entity/Product/Exceptions/AdFreezedByDealException.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Exceptions; 12 | 13 | class AdFreezedByDealException extends \Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/Entity/Product/Exceptions/AdWithoutVariationException.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Exceptions; 12 | 13 | class AdWithoutVariationException extends \Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/Entity/Order/Buyer/Phone.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Buyer; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractPhone; 14 | 15 | final class Phone extends AbstractPhone 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/Seller/Phone.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Seller; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractPhone; 14 | 15 | final class Phone extends AbstractPhone 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/City.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractLocation; 14 | 15 | class City extends AbstractLocation 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/State.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractLocation; 14 | 15 | class State extends AbstractLocation 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/Country.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractLocation; 14 | 15 | class Country extends AbstractLocation 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | insert_final_newline = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 4 10 | 11 | # tabs 2 spaces for makefiles 12 | [{Makefike,*.mk}] 13 | indent_style = tabs 14 | 15 | [*.{js,py,yml,yaml,json,css,scss,xml,html,sh}] 16 | indent_size = 2 17 | indent_style = space 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | indent_style = tab 22 | 23 | [vendor/**] 24 | trim_trailing_whitespace = false 25 | insert_final_newline = false 26 | -------------------------------------------------------------------------------- /src/Entity/Order/Buyer/AlternativePhone.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Buyer; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractPhone; 14 | 15 | final class AlternativePhone extends AbstractPhone 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/Seller/AlternativePhone.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Seller; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\AbstractPhone; 14 | 15 | final class AlternativePhone extends AbstractPhone 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Entity/Order/map/status.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | return [ 12 | 'APPROVED' => 'PAID', 13 | 'PROCESSING' => 'HANDLING', 14 | 'INVOICED' => 'INVOICED', 15 | 'SHIPPED' => 'SHIPPED', 16 | 'DELIVERED' => 'DELIVERED', 17 | 'CANCELED' => 'CANCELED', 18 | ]; 19 | -------------------------------------------------------------------------------- /src/Entity/Message/map/restful.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | return [ 12 | 'findByOrderId' => [ 13 | 'GET', 14 | '/messages/orders/{itemId}?&offset={offset}&limit={limit}', 15 | ], 16 | 'create' => [ 17 | 'POST', 18 | '/messages/?', 19 | ], 20 | ]; 21 | -------------------------------------------------------------------------------- /.rmt.yml: -------------------------------------------------------------------------------- 1 | _default: 2 | vcs: git 3 | prerequisites: 4 | - display-last-changes 5 | version-generator: simple 6 | version-persister: 7 | vcs-tag: 8 | tag-prefix: "{branch-name}_" 9 | post-release-actions: 10 | vcs-publish: 11 | ask-confirmation: true 12 | master: 13 | version-generator: semantic 14 | version-persister: 15 | vcs-tag: 16 | tag-prefix: '' 17 | pre-release-actions: 18 | changelog-update: 19 | format: semantic 20 | file: CHANGELOG.md 21 | dump-commits: true 22 | vcs-commit: ~ 23 | -------------------------------------------------------------------------------- /bin/mercadolivre-sdk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | * For more information, see . 10 | */ 11 | 12 | namespace Gpupo\MercadolivreSdk\Console; 13 | 14 | require dirname(__DIR__).'/config/bootstrap.php'; 15 | 16 | use Gpupo\MercadolivreSdk\Console\Application; 17 | 18 | $app = new Application("mercadolivre-sdk"); 19 | $app->init(__NAMESPACE__, dirname(__DIR__)); 20 | -------------------------------------------------------------------------------- /config/cli-config.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | use Doctrine\ORM\Tools\Console\ConsoleRunner; 12 | use Gpupo\MercadolivreSdk\Tests\Bootstrap; 13 | 14 | require __DIR__.'/bootstrap.php'; 15 | 16 | $entityManager = Bootstrap::factoryDoctrineEntityManager(); 17 | 18 | return ConsoleRunner::createHelperSet($entityManager); 19 | -------------------------------------------------------------------------------- /src/Entity/Order/Decorator/DecoratorInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Decorator; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | 15 | interface DecoratorInterface 16 | { 17 | public function setOrder(Order $order); 18 | 19 | public function validate(); 20 | } 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | os: 3 | - linux 4 | services: 5 | - mysql 6 | php: 7 | - 8.0 8 | - 7.4 9 | - nightly 10 | jobs: 11 | allow_failures: 12 | - php: nightly 13 | matrix: 14 | fast_finish: true 15 | before_install: 16 | - mysql -e 'CREATE DATABASE IF NOT EXISTS app;' 17 | - mysql -u root -e "CREATE USER 'app_db_user'@'localhost' IDENTIFIED BY 'app8as3';" 18 | - mysql -u root -e "GRANT ALL ON app.* TO 'app_db_user'@'localhost';" 19 | before_script: 20 | - composer self-update --2 21 | - composer install --prefer-dist 22 | - rm -f .env.local 23 | - vendor/bin/doctrine orm:schema-tool:update --force 24 | 25 | script: composer run-script test 26 | notifications: 27 | email: false 28 | -------------------------------------------------------------------------------- /src/Client/Ml.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Client; 12 | 13 | use Meli; 14 | 15 | class Ml extends Meli 16 | { 17 | public function setRefreshToken($refresh_token) 18 | { 19 | $this->refresh_token = $refresh_token; 20 | } 21 | 22 | public function getAuthRedirectUrl($url) 23 | { 24 | return $this->getAuthUrl($url, self::$AUTH_URL['MLB']); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Entity/Message/UserCollection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\CollectionAbstract; 15 | 16 | class UserCollection extends CollectionAbstract implements CollectionInterface 17 | { 18 | public function factoryElement($data) 19 | { 20 | return new User($data); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Entity/Message/MessageCollection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\Common\Entity\CollectionAbstract; 14 | use Gpupo\Common\Entity\CollectionInterface; 15 | 16 | final class MessageCollection extends CollectionAbstract implements CollectionInterface 17 | { 18 | public function factoryElement($data) 19 | { 20 | return new Message($data); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /config/bootstrap.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | use Symfony\Component\Dotenv\Dotenv; 12 | 13 | if (!class_exists('\Gpupo\Common\Console\Application')) { 14 | require __DIR__.'/../vendor/autoload.php'; 15 | } 16 | 17 | if (!class_exists(Dotenv::class)) { 18 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); 19 | } 20 | // load all the .env files 21 | (new Dotenv(true))->loadEnv(dirname(__DIR__).'/.env'); 22 | -------------------------------------------------------------------------------- /src/Entity/Order/Payments/Collector.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Payments; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Collector extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'integer', 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Entity/Order/Payments/Collection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Payments; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\CollectionAbstract; 15 | use Gpupo\CommonSdk\Entity\CollectionContainerInterface; 16 | 17 | final class Collection extends CollectionAbstract implements CollectionInterface, CollectionContainerInterface 18 | { 19 | public function factoryElement($data) 20 | { 21 | return new Payment($data); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Entity/Product/Pictures/Collection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Pictures; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\CollectionAbstract; 15 | use Gpupo\CommonSdk\Entity\CollectionContainerInterface; 16 | 17 | final class Collection extends CollectionAbstract implements CollectionInterface, CollectionContainerInterface 18 | { 19 | public function factoryElement($data) 20 | { 21 | return new Picture($data); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Entity/AbstractLocation.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | abstract class AbstractLocation extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'integer', 25 | 'name' => 'string', 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/Speed.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Speed extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'handling' => 'string', 25 | 'shipping' => 'string', 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entity/Order/StatusDetail.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | final class StatusDetail extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'code' => 'string', 25 | 'description' => 'string', 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entity/Order/Buyer/BillingInfo.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Buyer; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class BillingInfo extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'doc_type' => 'string', 25 | 'doc_number' => 'string', 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/ShippingItems/Collection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping\ShippingItems; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\CollectionAbstract; 15 | use Gpupo\CommonSdk\Entity\CollectionContainerInterface; 16 | 17 | final class Collection extends CollectionAbstract implements CollectionInterface, CollectionContainerInterface 18 | { 19 | public function factoryElement($data) 20 | { 21 | return new Item($data); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Entity/Order/map/schema.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | return [ 12 | 'id' => 'integer', 13 | 'pack_id' => 'string', 14 | 'status' => 'string', 15 | 'status_detail' => 'object', 16 | 'date_created' => 'string', 17 | 'date_closed' => 'string', 18 | 'order_items' => 'object', 19 | 'total_amount' => 'number', 20 | 'currency_id' => 'string', 21 | 'buyer' => 'object', 22 | 'seller' => 'object', 23 | 'payments' => 'object', 24 | 'feedback' => 'array', 25 | 'shipping' => 'object', 26 | 'tags' => 'array', 27 | ]; 28 | -------------------------------------------------------------------------------- /src/Entity/Order/Decorator/Status/Processing.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\AbstractDecorator; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\DecoratorInterface; 15 | 16 | class Processing extends AbstractDecorator implements DecoratorInterface 17 | { 18 | protected $name = 'Processing'; 19 | 20 | protected function factoryArray() 21 | { 22 | return [ 23 | 'status' => 'handling', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Entity/Order/Payments/AtmTransferReference.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Payments; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class AtmTransferReference extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'company_id' => 'integer', 25 | 'transaction_id' => 'integer', 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entity/Order/OrderCollection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\MercadolivreSdk\Entity\AbstractMetadata; 15 | 16 | final class OrderCollection extends AbstractMetadata implements CollectionInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | protected function getKey() 22 | { 23 | return 'results'; 24 | } 25 | 26 | protected function factoryEntity(array $data) 27 | { 28 | return new Order($data); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Entity/Message/Text.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Text extends EntityAbstract implements EntityInterface 17 | { 18 | protected function setUp() 19 | { 20 | $this->setRequiredSchema(['plain']); 21 | } 22 | 23 | /** 24 | * @codeCoverageIgnore 25 | */ 26 | public function getSchema(): array 27 | { 28 | return [ 29 | 'plain' => 'string', 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Entity/Product/ProductCollection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product; 12 | 13 | use Gpupo\Common\Entity\CollectionAbstract; 14 | use Gpupo\Common\Entity\CollectionInterface; 15 | 16 | final class ProductCollection extends CollectionAbstract implements CollectionInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | protected function getKey() 22 | { 23 | return 'results'; 24 | } 25 | 26 | protected function factoryEntity($id) 27 | { 28 | return new Product(['id' => $id]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/EstimatedDelivery.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class EstimatedDelivery extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'date' => 'string', 25 | 'time_from' => 'string', 26 | 'time_to' => 'string', 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Entity/AbstractPhone.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | abstract class AbstractPhone extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'area_code' => 'integer', 25 | 'extension' => 'string', 26 | 'number' => 'string', 27 | 'verified' => 'bool', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | branches: 5 | - master 6 | - develop 7 | - verbose 8 | paths-ignore: 9 | - '**.md' 10 | - 'examples/**' 11 | create: 12 | tags: 13 | - 5.* 14 | - 6.* 15 | jobs: 16 | run: 17 | name: Run 18 | runs-on: ${{ matrix.operating-system }} 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | operating-system: [ubuntu-latest] 23 | php-versions: ['7.4'] 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v1 27 | with: 28 | fetch-depth: 1 29 | - name: Validate composer.json and composer.lock 30 | run: composer validate 31 | 32 | - name: Install dependencies 33 | run: composer install --prefer-dist --no-progress --no-suggest --no-scripts 34 | 35 | - name: Run test suite 36 | run: composer run-script test 37 | -------------------------------------------------------------------------------- /Resources/mockup/Message/creationResponse.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "message_id": "0033b582a1474fa98c02d229abcec43c", 4 | "date_received": "2016-09-01T05:15:25.821Z", 5 | "date": "2016-09-01T05:15:25.821Z", 6 | "date_available": "2016-09-01T05:15:25.821Z", 7 | "date_notified": null, 8 | "date_read": null, 9 | "from": { 10 | "user_id": "123456789", 11 | "email": null, 12 | "name": null 13 | }, 14 | "to": [ 15 | { 16 | "user_id": "123456780", 17 | "email": null 18 | } 19 | ], 20 | "subject": "Test Item subject", 21 | "text": { 22 | "plain": "Ejemplo de texto" 23 | }, 24 | "attachments": [ 25 | ], 26 | "attachments_validations": { 27 | }, 28 | "site_id": "MLA", 29 | "resource": "orders", 30 | "resource_id": "1234567871", 31 | "status": "available", 32 | "moderation": { 33 | "status": "non_moderated" 34 | } 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /tests/Entity/Order/Decorator/Status/ShippedTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Decorator\Status; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status\Shipped; 14 | use Gpupo\MercadolivreSdk\Tests\Entity\Order\Decorator\AbstractDecoratorTestCase; 15 | 16 | /** 17 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status\Shipped 18 | */ 19 | class ShippedTest extends AbstractDecoratorTestCase 20 | { 21 | protected $target = 'Shipped'; 22 | 23 | protected function factory($data = []) 24 | { 25 | return new Shipped($data); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/ShippingItems/Item.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping\ShippingItems; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | final class Item extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'description' => 'string', 25 | 'dimensions' => 'string', 26 | 'id' => 'string', 27 | 'quantity' => 'integer', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Entity/Order/Decorator/Status/ProcessingTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Decorator\Status; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status\Processing; 14 | use Gpupo\MercadolivreSdk\Tests\Entity\Order\Decorator\AbstractDecoratorTestCase; 15 | 16 | /** 17 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status\Processing 18 | */ 19 | class ProcessingTest extends AbstractDecoratorTestCase 20 | { 21 | protected $target = 'Processing'; 22 | 23 | protected function factory($data = []) 24 | { 25 | return new Processing($data); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CS sniffs 5 | 6 | 7 | 8 | 9 | 10 | 1 11 | 12 | 13 | 1 14 | 15 | 16 | 1 17 | 18 | 19 | src 20 | 21 | */vendor/* 22 | */tests/* 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Entity/Order/Order.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | use Gpupo\CommonSdk\Traits\LoadTrait; 16 | 17 | final class Order extends EntityAbstract implements EntityInterface 18 | { 19 | use LoadTrait; 20 | 21 | protected $primaryKey = 'id'; 22 | 23 | public function getSchema(): array 24 | { 25 | return $this->loadArrayFromFile(__DIR__.'/map/schema.map.php'); 26 | } 27 | 28 | public function check() 29 | { 30 | $this->setRequiredSchema(['id']); 31 | 32 | return $this->isValid(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Entity/Product/Pictures/Picture.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product\Pictures; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Picture extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'string', 25 | 'url' => 'string', 26 | 'secure_url' => 'string', 27 | 'size' => 'string', 28 | 'max_size' => 'string', 29 | 'quality' => 'string', 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Entity/Order/map/translate.foreign.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | $shipping = ''; 12 | if ($foreign->get('tracking')) { 13 | $shipping = [ 14 | 'shippingCode' => $foreign->get('tracking')['trackingNumber'], 15 | ]; 16 | } 17 | 18 | return [ 19 | 'id' => $foreign->get('orderNumber'), 20 | 'status' => $foreign->get('orderStatus'), 21 | 'status_detail' => '', 22 | 'date_created' => '', 23 | 'date_closed' => '', 24 | 'order_items' => '', 25 | 'total_amount' => '', 26 | 'currency_id' => '', 27 | 'buyer' => '', 28 | 'seller' => '', 29 | 'payments' => '', 30 | 'feedback' => '', 31 | 'shipping' => $shipping, 32 | 'tags' => '', 33 | ]; 34 | -------------------------------------------------------------------------------- /src/Entity/GenericManager.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity; 12 | 13 | use Gpupo\CommonSdk\Map; 14 | 15 | final class GenericManager extends AbstractManager 16 | { 17 | public function factorySimpleMap(array $route, array $parameters = null) 18 | { 19 | $pars = array_merge($this->fetchDefaultParameters(), (array) $parameters); 20 | $map = new Map($route, $pars); 21 | 22 | return $map; 23 | } 24 | 25 | public function getFromRoute(array $route, array $parameters = null) 26 | { 27 | $map = $this->factorySimpleMap($route, $parameters); 28 | $perform = $this->perform($map); 29 | 30 | return $perform->getData(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Entity/Order/Decorator/Status/Shipped.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Decorator\Status; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\AbstractDecorator; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Decorator\DecoratorInterface; 15 | 16 | class Shipped extends AbstractDecorator implements DecoratorInterface 17 | { 18 | protected $name = 'Shipped'; 19 | 20 | protected function factoryArray() 21 | { 22 | return [ 23 | 'tracking_number' => $this->getOrder()->getShipping()->getShippingCode(), 24 | 'service_id' => ('Expresso' === $this->getOriginalOrder()->getShipping()->getShippingOption()->getName()) ? 22 : 21, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Entity/Order/Seller/Seller.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Seller; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Seller extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'integer', 25 | 'nickname' => 'string', 26 | 'email' => 'string', 27 | 'phone' => 'object', 28 | 'alternative_phone' => 'object', 29 | 'first_name' => 'string', 30 | 'last_name' => 'string', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CS sniffs 5 | 6 | 7 | 8 | 9 | 10 | 1 11 | 12 | 13 | 1 14 | 15 | 16 | 1 17 | 18 | 19 | src 20 | tests 21 | */*.map.php 22 | */vendor/* 23 | */tests/* 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Entity/Order/OrderItems/Collection.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\OrderItems; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\CollectionAbstract; 15 | use Gpupo\CommonSdk\Entity\CollectionContainerInterface; 16 | 17 | final class Collection extends CollectionAbstract implements CollectionInterface, CollectionContainerInterface 18 | { 19 | public function factoryElement($data) 20 | { 21 | if (\is_array($data)) { 22 | if (\array_key_exists('item', $data)) { 23 | $data = array_merge($data, $data['item']); 24 | unset($data['item']); 25 | } 26 | } 27 | 28 | return new Item($data); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Entity/Order/Buyer/Buyer.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Buyer; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Buyer extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'integer', 25 | 'nickname' => 'string', 26 | 'email' => 'string', 27 | 'phone' => 'object', 28 | 'alternative_phone' => 'object', 29 | 'first_name' => 'string', 30 | 'last_name' => 'string', 31 | 'billing_info' => 'object', 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Entity/Message/User.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class User extends EntityAbstract implements EntityInterface 17 | { 18 | protected function setUp() 19 | { 20 | $this->setOptionalSchema(['email', 'name', 'site_id', 'resource', 'resource_id']); 21 | } 22 | 23 | /** 24 | * @codeCoverageIgnore 25 | */ 26 | public function getSchema(): array 27 | { 28 | return [ 29 | 'user_id' => 'integer', 30 | 'email' => 'string', 31 | 'resource' => 'string', 32 | 'resource_id' => 'string', 33 | 'site_id' => 'string', 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/ShippingOption.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class ShippingOption extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'cost' => 'number', 25 | 'list_cost' => 'number', 26 | 'currency_id' => 'string', 27 | 'estimated_delivery' => 'object', 28 | 'id' => 'integer', 29 | 'name' => 'string', 30 | 'shipping_method_id' => 'integer', 31 | 'speed' => 'object', 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Gilmar Pupo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Resources/mockup/Message/item.json: -------------------------------------------------------------------------------- 1 | { 2 | "message_id": "0033b582a1474fa98c02d229abcec43c", 3 | "date_received": "2016-09-01T05:15:25.821Z", 4 | "date": "2016-09-01T05:15:25.821Z", 5 | "date_available": "2016-09-01T05:15:25.821Z", 6 | "date_notified": "2016-09-01T05:17:42.945Z", 7 | "date_read": "2016-09-01T21:31:19.606Z", 8 | "from": { 9 | "user_id": "123456789", 10 | "email": "userfrom.n4tx9d+2-ogeytenjqgi3tomjw@mail.mercadolibre.com", 11 | "name": "User from" 12 | }, 13 | "to": [ 14 | { 15 | "user_id": "123456780", 16 | "email": "userto.3fd70y+2-ogeytenjqgi3tombx@mail.mercadolibre.com" 17 | } 18 | ], 19 | "subject": "Test Item subject", 20 | "text": { 21 | "plain": "Ejemplo de texto" 22 | }, 23 | "attachments": [ 24 | {} 25 | ], 26 | "attachments_validations": { 27 | "invalid_size": [ 28 | ], 29 | "invalid_extension": [ 30 | ], 31 | "forbidden": [ 32 | ], 33 | "internal_error": [ 34 | ] 35 | }, 36 | "site_id": "MLA", 37 | "resource": "orders", 38 | "resource_id": "1234567871", 39 | "status": "available", 40 | "moderation": { 41 | "status": "non_moderated" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Entity/User/Manager.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\User; 12 | 13 | use Gpupo\CommonSdk\Traits\LoadTrait; 14 | use Gpupo\CommonSdk\Traits\TranslatorManagerTrait; 15 | use Gpupo\MercadolivreSdk\Entity\AbstractManager; 16 | 17 | final class Manager extends AbstractManager 18 | { 19 | use LoadTrait; 20 | use TranslatorManagerTrait; 21 | 22 | protected $entity = 'User'; 23 | 24 | /** 25 | * @codeCoverageIgnore 26 | */ 27 | protected function setUp() 28 | { 29 | $this->maps = $this->loadArrayFromFile(__DIR__.'/map/restful.map.php'); 30 | } 31 | 32 | public function profile() 33 | { 34 | $responseJson = $this->perform($this->factoryMap('me', [])); 35 | 36 | $results = $this->processResponse($responseJson); 37 | 38 | return $results; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Entity/Order/StatusDetailTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 15 | 16 | /** 17 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\StatusDetail 18 | */ 19 | class StatusDetailTest extends TestCaseAbstract 20 | { 21 | public function testIsAObjectOfOrder() 22 | { 23 | $order = new Order([ 24 | 'id' => 'Foo12233', 25 | 'status_detail' => [ 26 | 'code' => 'bar', 27 | 'description' => 'Hello World', 28 | ], 29 | ]); 30 | 31 | $this->assertSame('bar', $order->getStatusDetail()->getCode()); 32 | $this->assertSame('Hello World', $order->getStatusDetail()->getDescription()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Entity/Product/map/translate.foreign.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | $extras = $foreign->get('extras'); 12 | $sku = $foreign->get('skus')[0]; 13 | 14 | $imgList = []; 15 | foreach ($sku['images'] as $image) { 16 | $imgList[] = ['source' => $image['url']]; 17 | } 18 | 19 | $array = [ 20 | 'title' => mb_substr($sku['name'], 0, 60), 21 | 'available_quantity' => $sku['stock'], 22 | 'price' => $sku['sellPrice'], 23 | 'description' => $sku['description'], 24 | 'pictures' => $imgList, 25 | 'category_id' => $extras['category'], 26 | 'currency_id' => $extras['currency_id'], 27 | 'buying_mode' => $extras['buying_mode'], 28 | 'listing_type_id' => $extras['listing_type_id'], 29 | 'condition' => $extras['condition'], 30 | 'shipping' => $extras['shipping'], 31 | 'official_store_id' => $extras['official_store_id'], 32 | ]; 33 | 34 | return $array; 35 | -------------------------------------------------------------------------------- /src/Entity/AbstractMetadata.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity; 12 | 13 | use Gpupo\Common\Entity\ArrayCollection; 14 | use Gpupo\CommonSdk\Entity\Metadata\MetadataContainerAbstract; 15 | use Gpupo\CommonSdk\Traits\FinderTrait; 16 | 17 | abstract class AbstractMetadata extends MetadataContainerAbstract 18 | { 19 | use FinderTrait; 20 | 21 | protected function cutMetadata($raw) 22 | { 23 | if (empty($raw) || !\is_array($raw)) { 24 | return [[]]; 25 | } 26 | 27 | unset($raw['results']); 28 | 29 | return $raw; 30 | } 31 | 32 | protected function normalizeMetas($metas) 33 | { 34 | foreach ($metas as $key => $value) { 35 | if (\is_array($value)) { 36 | $metas[$key] = new ArrayCollection($value); 37 | } 38 | } 39 | 40 | return $metas; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/ReceiverAddress.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class ReceiverAddress extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'address_line' => 'string', 25 | 'city' => 'object', 26 | 'comment' => 'string', 27 | 'country' => 'object', 28 | 'id' => 'integer', 29 | 'latitude' => 'string', 30 | 'longitude' => 'string', 31 | 'state' => 'object', 32 | 'street_name' => 'string', 33 | 'street_number' => 'string', 34 | 'zip_code' => 'string', 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gpupo/mercadolivre-sdk", 3 | "description": "SDK Não Oficial para integração a partir de aplicações PHP com APIs Mercadolivre", 4 | "homepage": "https://opensource.gpupo.com/mercadolivre-sdk/", 5 | "authors": [ 6 | { 7 | "name": "Gilmar Pupo", 8 | "email": "contact@gpupo.com" 9 | } 10 | ], 11 | "keywords": ["mercadolivre", "marketplace", "sdk", "api"], 12 | "license": "MIT", 13 | "require": { 14 | "php": ">=7.4 || ^8.0", 15 | "gpupo/common-sdk": "^5.4 || ^6.5" 16 | }, 17 | "require-dev": { 18 | "gpupo/common-dev": "*" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Gpupo\\MercadolivreSdk\\": "src" 23 | }, 24 | "classmap": [ 25 | "Resources/3rd/mercadolibre/" 26 | ] 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "Gpupo\\MercadolivreSdk\\Tests\\": "tests" 31 | } 32 | }, 33 | "bin": ["bin/mercadolivre-sdk"], 34 | "scripts": { 35 | "test": "phpunit" 36 | }, 37 | "config": { 38 | "preferred-install": "dist" 39 | }, 40 | "minimum-stability": "dev", 41 | "prefer-stable": true 42 | } 43 | -------------------------------------------------------------------------------- /tests/Client/ClientTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Client; 12 | 13 | use Gpupo\CommonSdk\Client\ClientInterface; 14 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 15 | 16 | /** 17 | * @coversNothing 18 | */ 19 | class ClientTest extends TestCaseAbstract 20 | { 21 | /** 22 | * @covers \Gpupo\MercadolivreSdk\Client\Client::getDefaultOptions 23 | * @covers \Gpupo\MercadolivreSdk\Client\Client::renderAuthorization 24 | */ 25 | public function testSucessoAoDefinirOptions() 26 | { 27 | $client = $this->factoryClient(); 28 | $this->assertInstanceOf(ClientInterface::class, $client); 29 | 30 | return $client; 31 | } 32 | 33 | /** 34 | * @depends testSucessoAoDefinirOptions 35 | */ 36 | public function testGerenciaUriDeRecurso(ClientInterface $client) 37 | { 38 | $this->assertSame( 39 | 'https://api.mercadolibre.com/items/MLB12343412/descriptions', 40 | $client->getResourceUri('/items/MLB12343412/descriptions') 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Console/Command/Auth/ChecklistCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Auth; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputInterface; 15 | use Symfony\Component\Console\Output\OutputInterface; 16 | 17 | /** 18 | * @codeCoverageIgnore 19 | */ 20 | final class ChecklistCommand extends AbstractCommand 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function configure() 26 | { 27 | $this 28 | ->setName(self::NAME_PREFIX.'auth:checklist') 29 | ->setDescription('Check Mercado Livre files'); 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | protected function execute(InputInterface $input, OutputInterface $output) 36 | { 37 | $data = $this->getProjectData(); 38 | 39 | if (!\array_key_exists('access_token', $data)) { 40 | throw new \Exception('Access Token required!'); 41 | } 42 | 43 | $output->writeln('token:'.$data['access_token']); 44 | 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Console/Command/AbstractCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command; 12 | 13 | use Gpupo\CommonSdk\Console\Command\AbstractCommand as Core; 14 | use Symfony\Component\Console\Input\InputOption; 15 | 16 | /** 17 | * @codeCoverageIgnore 18 | */ 19 | abstract class AbstractCommand extends Core 20 | { 21 | const NAME_PREFIX = 'markethub:mercadolivre:'; 22 | 23 | public function getProjectDataFilename(): string 24 | { 25 | return sprintf('var/data/markethub-mercadolivre-%d.yaml', $this->getFactory()->getOptions()->get('client_id')); 26 | } 27 | 28 | protected function addOptionsForList() 29 | { 30 | $this 31 | ->addOption( 32 | 'offset', 33 | null, 34 | InputOption::VALUE_REQUIRED, 35 | 'Current offset of list', 36 | 0 37 | ) 38 | ->addOption( 39 | 'max', 40 | null, 41 | InputOption::VALUE_REQUIRED, 42 | 'Max items quantity', 43 | 100 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Entity/Order/Shipping/Shipping.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Shipping extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'cost' => 'integer', 25 | 'currency_id' => 'string', 26 | 'date_created' => 'string', 27 | 'date_first_printed' => 'string', 28 | 'id' => 'integer', 29 | 'picking_type' => 'string', 30 | 'receiver_address' => 'object', 31 | 'sender_id' => 'integer', 32 | 'service_id' => 'integer', 33 | 'shippingCode' => 'string', 34 | 'shipment_type' => 'string', 35 | 'shipping_items' => 'object', 36 | 'shipping_mode' => 'string', 37 | 'shipping_option' => 'object', 38 | 'status' => 'string', 39 | 'substatus' => 'string', 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Console/Command/Schema/OrderCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Schema; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | use Symfony\Component\Yaml\Yaml; 18 | 19 | /** 20 | * @codeCoverageIgnore 21 | */ 22 | final class OrderCommand extends AbstractCommand 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this 30 | ->setName(self::NAME_PREFIX.'schema:order') 31 | ->setDescription('Dump Order Schema'); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | protected function execute(InputInterface $input, OutputInterface $output) 38 | { 39 | $order = new Order(); 40 | $schema = $this->getSchema($order); 41 | $this->writeInfo($output, $schema); 42 | $content = Yaml::dump($schema, 8); 43 | 44 | file_put_contents('Resources/schema/order.yaml', $content); 45 | 46 | return 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Console/Command/Schema/ProductCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Schema; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Gpupo\MercadolivreSdk\Entity\Product\Product; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | use Symfony\Component\Yaml\Yaml; 18 | 19 | /** 20 | * @codeCoverageIgnore 21 | */ 22 | final class ProductCommand extends AbstractCommand 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this 30 | ->setName(self::NAME_PREFIX.'schema:product') 31 | ->setDescription('Dump Product Schema'); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | protected function execute(InputInterface $input, OutputInterface $output) 38 | { 39 | $product = new Product(); 40 | $schema = $this->getSchema($product); 41 | $this->writeInfo($output, $schema); 42 | $content = Yaml::dump($schema, 8); 43 | 44 | file_put_contents('Resources/schema/product.yaml', $content); 45 | 46 | return 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Entity/Product/map/translate.native.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | $skusList = []; 12 | if ($native) { 13 | foreach ($native as $sku) { 14 | $sellPrice = $sku->getPrice(); 15 | $skusList[] = [ 16 | 'skuId' => $sku->getId(), 17 | 'gtin' => $sku->getEanIsbn(), 18 | 'name' => $sku->getName(), 19 | 'description' => $sku->getDescription(), 20 | 'color' => $sku->getColor(), 21 | 'size' => $sku->getSize(), 22 | 'gender' => $sku->getGender(), 23 | 'height' => $sku->getHeight(), 24 | 'width' => $sku->getWidth(), 25 | 'depth' => $sku->getDepth(), 26 | 'weight' => $sku->getWeight(), 27 | 'listPrice' => $sellPrice, 28 | 'sellPrice' => $sellPrice, 29 | 'stock' => $sku->getStock()->getAvailable(), 30 | 'status' => $sku->getStatus()->getActive(), 31 | ]; 32 | } 33 | } 34 | 35 | return [ 36 | 'productId' => $native->getId(), 37 | 'productType' => $native->getProductType(), 38 | 'department' => $native->getCategoryId(), 39 | 'category' => '', 40 | 'brand' => $native->getBrand(), 41 | 'skus' => $skusList, 42 | ]; 43 | -------------------------------------------------------------------------------- /tests/Entity/Order/OrderItems/ItemTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\OrderItems; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | use Gpupo\MercadolivreSdk\Entity\Order\OrderCollection; 15 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\OrderItems\Collection 19 | */ 20 | class ItemTest extends TestCaseAbstract 21 | { 22 | public function dataProvider() 23 | { 24 | $list = []; 25 | $collection = new OrderCollection($this->getResourceJson('mockup/Order/list-private.json')); 26 | 27 | foreach ($collection as $order) { 28 | $list[] = [$order]; 29 | } 30 | 31 | return $list; 32 | } 33 | 34 | /** 35 | * @dataProvider dataProvider 36 | */ 37 | public function testIsACollectionOfItems(Order $order) 38 | { 39 | foreach ($order->getOrderItems() as $item) { 40 | $this->assertStringStartsWith('MLB', $item->getId()); 41 | $this->assertSame('BRL', $item->getCurrencyId()); 42 | $this->assertStringStartsWith('gold', $item->get('listing_type_id')); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Entity/Message/Message.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Message extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | '_id' => 'string', 25 | 'message_id' => 'string', 26 | 'date' => 'string', 27 | 'date_received' => 'string', 28 | 'date_available' => 'string', 29 | 'date_notified' => 'string', 30 | 'date_read' => 'string', 31 | 'from' => 'object', 32 | 'to' => 'object', 33 | 'subject' => 'string', 34 | 'text' => 'object', 35 | 'client_id' => 'integer', 36 | 'attachments' => 'array', 37 | ]; 38 | } 39 | 40 | public function toCreation(): array 41 | { 42 | return $this->partitionByArrayKey([ 43 | 'from', 44 | 'to', 45 | 'subject', 46 | 'text', 47 | 'attachments', 48 | ]); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Entity/Product/Product.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Product extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'string', 25 | 'title' => 'string', 26 | 'description' => 'array', 27 | 'category_id' => 'string', 28 | 'price' => 'number', 29 | 'currency_id' => 'string', 30 | 'buying_mode' => 'string', 31 | 'listing_type_id' => 'string', 32 | 'condition' => 'string', 33 | 'pictures' => 'object', 34 | 'available_quantity' => 'number', 35 | 'shipping' => 'array', 36 | 'official_store_id' => 'string', 37 | 'status' => 'string', 38 | 'seller_id' => 'string', 39 | 'permalink' => 'string', 40 | 'attributes' => 'array', 41 | 'sold_quantity' => 'integer', 42 | 'video_id' => 'string', 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Entity/Order/OrderItems/Item.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\OrderItems; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | use Gpupo\CommonSdk\Traits\LoadTrait; 16 | 17 | final class Item extends EntityAbstract implements EntityInterface 18 | { 19 | use LoadTrait; 20 | 21 | protected $primaryKey = 'id'; 22 | 23 | /** 24 | * @codeCoverageIgnore 25 | */ 26 | public function getSchema(): array 27 | { 28 | return [ 29 | 'id' => 'string', 30 | 'title' => 'string', 31 | 'category_id' => 'string', 32 | 'variation_id' => 'string', 33 | 'quantity' => 'integer', 34 | 'unit_price' => 'number', 35 | 'currency_id' => 'string', 36 | 'sale_fee' => 'number', 37 | 'condition' => 'string', 38 | 'warranty' => 'string', 39 | 'seller_custom_field' => 'string', 40 | 'variation_attributes' => 'array', 41 | 'differential_pricing_id' => 'integer', 42 | 'listing_type_id' => 'string', 43 | 'base_currency_id' => 'string', 44 | 'full_unit_price' => 'number', 45 | 'base_exchange_rate' => 'number', 46 | 'manufacturing_days' => 'integer', 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Entity/Order/Translator.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order; 12 | 13 | use Gpupo\CommonSchema\AbstractTranslator; 14 | use Gpupo\CommonSchema\TranslatorDataCollection; 15 | use Gpupo\CommonSchema\TranslatorException; 16 | use Gpupo\CommonSchema\TranslatorInterface; 17 | use Gpupo\CommonSdk\Traits\LoadTrait; 18 | 19 | final class Translator extends AbstractTranslator implements TranslatorInterface 20 | { 21 | use LoadTrait; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function export(): TranslatorDataCollection 27 | { 28 | if (!$this->getNative() instanceof Order) { 29 | throw new TranslatorException('Order missed!'); 30 | } 31 | 32 | return $this->factoryOutputCollection($this->loadMap('native')); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function import(): Order 39 | { 40 | if (!$this->getForeign() instanceof TranslatorDataCollection) { 41 | throw new TranslatorException('Foreign missed!'); 42 | } 43 | 44 | return new Order($this->loadMap('foreign')); 45 | } 46 | 47 | private function loadMap($name): array 48 | { 49 | $file = __DIR__.'/map/translate.'.$name.'.map.php'; 50 | $method = 'get'.ucfirst($name); 51 | 52 | return $this->loadArrayFromFile($file, [$name => $this->{$method}()]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Entity/Order/OrderItems/CollectionTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\OrderItems; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | use Gpupo\MercadolivreSdk\Entity\Order\OrderCollection; 15 | use Gpupo\MercadolivreSdk\Entity\Order\OrderItems\Collection; 16 | use Gpupo\MercadolivreSdk\Entity\Order\OrderItems\Item; 17 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 18 | 19 | /** 20 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\OrderItems\Collection 21 | */ 22 | class CollectionTest extends TestCaseAbstract 23 | { 24 | public function dataProvider() 25 | { 26 | $list = []; 27 | $collection = new OrderCollection($this->getResourceJson('mockup/Order/list-private.json')); 28 | 29 | foreach ($collection as $order) { 30 | $list[] = [$order]; 31 | } 32 | 33 | return $list; 34 | } 35 | 36 | /** 37 | * @dataProvider dataProvider 38 | */ 39 | public function testIsACollection(Order $order) 40 | { 41 | $this->assertInstanceOf(Collection::class, $order->getOrderItems()); 42 | } 43 | 44 | /** 45 | * @dataProvider dataProvider 46 | */ 47 | public function testIsACollectionOfItems(Order $order) 48 | { 49 | foreach ($order->getOrderItems() as $item) { 50 | $this->assertInstanceOf(Item::class, $item); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Console/Application.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console; 12 | 13 | use Gpupo\CommonSdk\Console\AbstractApplication; 14 | use Gpupo\CommonSdk\FactoryInterface; 15 | use Gpupo\MercadolivreSdk\Factory; 16 | use Psr\Log\LoggerInterface; 17 | use Symfony\Contracts\Cache\CacheInterface; 18 | 19 | final class Application extends AbstractApplication 20 | { 21 | protected $commonParameters = [ 22 | [ 23 | 'key' => 'client_id', 24 | ], 25 | [ 26 | 'key' => 'secret_key', 27 | ], 28 | [ 29 | 'key' => 'access_token', 30 | ], 31 | [ 32 | 'key' => 'env', 33 | 'options' => ['sandbox', 'api'], 34 | 'default' => 'sandbox', 35 | 'name' => 'Version', 36 | ], 37 | [ 38 | 'key' => 'sslVersion', 39 | 'options' => ['SecureTransport', 'TLS'], 40 | 'default' => 'SecureTransport', 41 | 'name' => 'SSL Version', 42 | ], 43 | [ 44 | 'key' => 'registerPath', 45 | 'default' => false, 46 | ], 47 | [ 48 | 'key' => 'app_url', 49 | ], 50 | ]; 51 | 52 | public function factorySdk(array $options, LoggerInterface $logger = null, CacheInterface $cache = null): FactoryInterface 53 | { 54 | return new Factory($options, $logger, $cache); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Entity/Order/OrderCollectionTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | use Gpupo\MercadolivreSdk\Entity\Order\OrderCollection; 15 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\OrderCollection 19 | */ 20 | class OrderCollectionTest extends TestCaseAbstract 21 | { 22 | /** 23 | * @testdox Is a Container of multiples Orders 24 | */ 25 | public function testIsAContainer() 26 | { 27 | $orderCollection = new OrderCollection($this->getData()); 28 | $this->assertInstanceOf(Order::class, $orderCollection->first()); 29 | 30 | return $orderCollection; 31 | } 32 | 33 | /** 34 | * @depends testIsAContainer 35 | */ 36 | public function testHasMetadata(OrderCollection $orderCollection) 37 | { 38 | $this->assertGreaterThan(3, $orderCollection->getMetadata()->count()); 39 | $paging = $orderCollection->getMetadata()->get('paging'); 40 | $this->assertSame(166, $paging->get('total'), 'Paging Total'); 41 | $sort = $orderCollection->getMetadata()->get('sort'); 42 | $this->assertSame('date_asc', $sort->get('id'), 'Sort'); 43 | } 44 | 45 | protected function getData() 46 | { 47 | return $this->getResourceJson('mockup/Order/list-private.json'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Entity/Product/Translator.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Product; 12 | 13 | use Gpupo\CommonSchema\AbstractTranslator; 14 | use Gpupo\CommonSchema\TranslatorDataCollection; 15 | use Gpupo\CommonSchema\TranslatorException; 16 | use Gpupo\CommonSchema\TranslatorInterface; 17 | use Gpupo\CommonSdk\Traits\LoadTrait; 18 | 19 | final class Translator extends AbstractTranslator implements TranslatorInterface 20 | { 21 | use LoadTrait; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function export(): TranslatorDataCollection 27 | { 28 | if (!$this->getNative() instanceof Product) { 29 | throw new TranslatorException('Product missed!'); 30 | } 31 | 32 | return $this->factoryOutputCollection($this->loadMap('native')); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function import(): Product 39 | { 40 | if (!$this->getForeign() instanceof TranslatorDataCollection) { 41 | throw new TranslatorException('Foreign missed!'); 42 | } 43 | $map = $this->loadMap('foreign'); 44 | 45 | return new Product($map); 46 | } 47 | 48 | private function loadMap($name): array 49 | { 50 | $file = __DIR__.'/map/translate.'.$name.'.map.php'; 51 | $method = 'get'.ucfirst($name); 52 | $pars = [$name => $this->{$method}()]; 53 | 54 | return $this->loadArrayFromFile($file, $pars); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Client/MlTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Client; 12 | 13 | use Gpupo\MercadolivreSdk\Client\Ml; 14 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 15 | use Meli; 16 | 17 | /** 18 | * @coversNothing 19 | */ 20 | class MlTest extends TestCaseAbstract 21 | { 22 | public function testLoad() 23 | { 24 | $meli = new Meli('1234', 'a secret', 'Access_Token', 'Refresh_Token'); 25 | $this->assertInstanceof(Meli::class, $meli); 26 | } 27 | 28 | public function testMlClass() 29 | { 30 | $meli = new Ml('1234', 'secret', 'Access_Token', 'Refresh_Token'); 31 | $this->assertInstanceof(Meli::class, $meli); 32 | $this->assertInstanceof(Ml::class, $meli); 33 | 34 | return $meli; 35 | } 36 | 37 | /** 38 | * @depends testMlClass 39 | */ 40 | public function testGetAuthUrl(Ml $ml) 41 | { 42 | $ru = 'https://www.foo.com/bar'; 43 | $redirect_uri = $ml->getAuthUrl($ru, 'https://auth.mercadolivre.com.br'); 44 | 45 | $this->assertSame('https://auth.mercadolivre.com.br/authorization?client_id=1234&response_type=code&redirect_uri='.urlencode($ru), $redirect_uri); 46 | } 47 | 48 | /** 49 | * @depends testMlClass 50 | */ 51 | public function testMakePath(Ml $ml) 52 | { 53 | $p = $ml->make_path('/items/MLB12343412/descriptions'); 54 | 55 | $this->assertSame('https://api.mercadolibre.com/items/MLB12343412/descriptions', $p); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Console/Command/Catalog/Product/ViewCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Catalog\Product; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputArgument; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | class ViewCommand extends AbstractCommand 19 | { 20 | /** 21 | * {@inheritdoc} 22 | */ 23 | protected function configure() 24 | { 25 | $this 26 | ->setName(self::NAME_PREFIX.'catalog:product:view') 27 | ->setDescription('Get the description of product on Mercado Livre') 28 | ->addArgument('id', InputArgument::REQUIRED, 'Mercado Livre Product Id'); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | protected function execute(InputInterface $input, OutputInterface $output) 35 | { 36 | $id = $input->getArgument('id'); 37 | 38 | $productManager = $this->getFactory()->factoryManager('product'); 39 | 40 | try { 41 | $product = $productManager->findById($id); 42 | 43 | if (!$product) { 44 | throw new \Exception('Product Not Found'); 45 | } 46 | 47 | $this->writeInfo($output, $product->toArray()); 48 | } catch (\Exception $exception) { 49 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 50 | } 51 | 52 | return 0; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Console/ApplicationTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Console; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Application; 14 | use Gpupo\MercadolivreSdk\Factory; 15 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 16 | use Symfony\Component\Console\Input\InputInterface; 17 | use Symfony\Component\Console\Output\OutputInterface; 18 | use Symfony\Component\Console\Tester\CommandTester; 19 | 20 | /** 21 | * @coversNothing 22 | */ 23 | class ApplicationTest extends TestCaseAbstract 24 | { 25 | /** 26 | * Dá acesso a ``Factory``. 27 | */ 28 | public function testFactorySdk() 29 | { 30 | $app = new Application(); 31 | 32 | $sdk = $app->factorySdk([ 33 | 'client_id' => 'x882ja', 34 | 'access_token' => '8998329jejd', 35 | ]); 36 | 37 | $this->assertInstanceOf(Factory::class, $sdk); 38 | } 39 | 40 | /** 41 | * Recebe novas funções. 42 | */ 43 | public function testAppendCommand() 44 | { 45 | $app = new Application(); 46 | 47 | $app->appendCommand('foo:bar', 'Test') 48 | ->setCode(function (InputInterface $input, OutputInterface $output) { 49 | $output->writeln('Hello World'); 50 | }); 51 | 52 | $command = $app->find('foo:bar'); 53 | $commandTester = new CommandTester($command); 54 | $commandTester->execute(['command' => $command->getName()]); 55 | $this->assertSame('Hello World', trim($commandTester->getDisplay())); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Factory.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk; 12 | 13 | use Gpupo\CommonSdk\FactoryAbstract; 14 | use Gpupo\CommonSdk\FactoryInterface; 15 | use Gpupo\MercadolivreSdk\Client\Client; 16 | 17 | /** 18 | * Construtor principal, estendido pelo Factory de MarkethubBundle. 19 | */ 20 | class Factory extends FactoryAbstract implements FactoryInterface 21 | { 22 | protected $name = 'mercadolivre-sdk'; 23 | 24 | public function setClient(array $clientOptions = []) 25 | { 26 | $this->client = new Client($clientOptions, $this->getLogger(), $this->getSimpleCache()); 27 | } 28 | 29 | public function getNamespace() 30 | { 31 | return '\\'.__NAMESPACE__.'\Entity\\'; 32 | } 33 | 34 | protected function getSchema(): array 35 | { 36 | return [ 37 | 'product' => [ 38 | 'class' => Entity\Product\Product::class, 39 | 'manager' => Entity\Product\Manager::class, 40 | ], 41 | 'order' => [ 42 | 'class' => Entity\Order\Order::class, 43 | 'manager' => Entity\Order\Manager::class, 44 | ], 45 | 'message' => [ 46 | 'class' => Entity\Message\Message::class, 47 | 'manager' => Entity\Message\Manager::class, 48 | ], 49 | 'generic' => [ 50 | 'manager' => Entity\GenericManager::class, 51 | ], 52 | 'user' => [ 53 | 'manager' => Entity\User\Manager::class, 54 | ], 55 | ]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Console/Command/User/MeCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\User; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputInterface; 15 | use Symfony\Component\Console\Output\OutputInterface; 16 | 17 | //use Gpupo\MercadolivreSdk\Entity\GenericManager; 18 | 19 | /** 20 | * @codeCoverageIgnore 21 | */ 22 | final class MeCommand extends AbstractCommand 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this 30 | ->setName(self::NAME_PREFIX.'user:me') 31 | ->setDescription('Mercado Livre user info'); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | protected function execute(InputInterface $input, OutputInterface $output) 38 | { 39 | $projectData = $this->getProjectData(); 40 | 41 | if (!\array_key_exists('user_id', $projectData)) { 42 | throw new \Exception('User Id required!'); 43 | } 44 | 45 | $this->getFactory()->getLogger()->info('Project Data', $projectData); 46 | $manager = $this->getFactory()->factoryManager('generic'); 47 | 48 | $output->writeln('---- APP INFO -------'); 49 | $this->writeInfo($output, $manager->getFromRoute(['GET', '/applications/{client_id}?'], $projectData)); 50 | 51 | $output->writeln('---- User INFO -------'); 52 | $this->writeInfo($output, $manager->getFromRoute(['GET', '/users/{user_id}?'], $projectData)); 53 | 54 | return 0; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Console/Command/Message/CreateCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Message; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputArgument; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | use Symfony\Component\Yaml\Yaml; 18 | 19 | class CreateCommand extends AbstractCommand 20 | { 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | protected function configure() 25 | { 26 | $this 27 | ->setName(self::NAME_PREFIX.'message:create') 28 | ->setDescription('Create a message on Mercado Livre') 29 | ->addArgument('filename', InputArgument::REQUIRED, 'YAML filename for Message compose'); 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | protected function execute(InputInterface $input, OutputInterface $output) 36 | { 37 | $filename = $input->getArgument('filename'); 38 | 39 | try { 40 | $data = Yaml::parseFile($filename); 41 | $message = $this->getFactory()->createMessage($data); 42 | $messageManager = $this->getFactory()->factoryManager('message'); 43 | $returnedMessage = $messageManager->create($message); 44 | $output->writeln(sprintf('Message received by ML at %s ', $returnedMessage->getDateReceived())); 45 | } catch (\Exception $exception) { 46 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 47 | } 48 | 49 | return 0; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Console/Command/Message/ListCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Message; 12 | 13 | use Gpupo\Common\Traits\TableTrait; 14 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 15 | use Symfony\Component\Console\Input\InputArgument; 16 | use Symfony\Component\Console\Input\InputInterface; 17 | use Symfony\Component\Console\Output\OutputInterface; 18 | 19 | class ListCommand extends AbstractCommand 20 | { 21 | use TableTrait; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | protected function configure() 27 | { 28 | $this 29 | ->setName(self::NAME_PREFIX.'message:list') 30 | ->setDescription('List a messages on Mercado Livre') 31 | ->addArgument('id', InputArgument::REQUIRED, 'Order ID'); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | protected function execute(InputInterface $input, OutputInterface $output) 38 | { 39 | $id = $input->getArgument('id'); 40 | 41 | try { 42 | $order = $this->getFactory()->createOrder(['id' => $id]); 43 | $messageManager = $this->getFactory()->factoryManager('message'); 44 | $messageCollection = $messageManager->findByOrderId($order); 45 | 46 | $output->writeln(sprintf('Total: %d ', $messageCollection->count())); 47 | $this->displayTableResults($output, $messageCollection); 48 | } catch (\Exception $exception) { 49 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 50 | } 51 | 52 | return 0; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | tests 19 | 20 | 21 | tests/Entity/Product/ 22 | 23 | 24 | tests/Entity/Order 25 | 26 | 27 | tests/Entity/Message 28 | 29 | 30 | 31 | 32 | 33 | src/ 34 | 35 | src/Console/ 36 | *.config.php 37 | *.map.php 38 | *.template.php 39 | 40 | 41 | 42 | 43 | 44 | large 45 | todo 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/Entity/Order/map/restful.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | $put = function () { 12 | return [ 13 | 'PUT', 14 | '/shipments/{shipmentId}?', 15 | ]; 16 | }; 17 | 18 | return [ 19 | 'save' => [ 20 | 'POST', 21 | '/orders', 22 | ], 23 | 'fetch' => [ 24 | 'GET', 25 | '/orders/search/recent?seller={user_id}&', 26 | ], 27 | 'findById' => [ 28 | 'GET', 29 | '/orders/{itemId}?', 30 | ], 31 | 'findShipmentById' => [ 32 | 'GET', 33 | '/shipments/{shipmentId}?', 34 | ], 35 | 'findCteByShipmentId' => [ 36 | 'GET', 37 | '/shipments/{shipmentId}/cte?doctype=xml&', 38 | ], 39 | 'findInvoiceByShipmentId' => [ 40 | 'GET', 41 | '/shipments/{shipmentId}/invoice_data?siteId=MLB' 42 | ], 43 | 'sendInvoiceToShipment' => [ 44 | 'POST', 45 | '/shipments/{shipmentId}/invoice_data?siteId=MLB' 46 | ], 47 | 'updateInvoiceToShipment' => [ 48 | 'PUT', 49 | '/shipments/{shipmentId}/invoice_data?siteId=MLB' 50 | ], 51 | 'billingInfo' => [ 52 | 'GET', 53 | '/orders/{itemId}/billing_info?', 54 | ], 55 | 'downloadTicket' => [ 56 | 'GET', 57 | '/shipment_labels?shipment_ids={shipmentId}&response_type=pdf', 58 | ], 59 | 'getOrdersRecent' => [ 60 | 'GET', 61 | '/orders/search?seller={user_id}&order.date_created.from={beginDate}T00:00:00.000-04:00&order.date_created.to={endDate}T00:00:00.000-04:00&offset={offset}&limit={limit}', 62 | ], 63 | 'toTracked' => $put(), 64 | 'toProcessing' => $put(), 65 | 'toShipped' => $put(), 66 | 'toDelivered' => $put(), 67 | 'toCanceled' => $put(), 68 | ]; 69 | -------------------------------------------------------------------------------- /src/Console/Command/Trading/Order/ListCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Trading\Order; 12 | 13 | use Gpupo\Common\Traits\TableTrait; 14 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | class ListCommand extends AbstractCommand 19 | { 20 | use TableTrait; 21 | 22 | private $limit = 50; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this 30 | ->setName(self::NAME_PREFIX.'trading:order:list') 31 | ->setDescription('Get the Order list on Mercado Livre') 32 | ->addOptionsForList(); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | protected function execute(InputInterface $input, OutputInterface $output) 39 | { 40 | $orderManager = $this->getFactory()->factoryManager('order'); 41 | $offset = $input->getOption('offset'); 42 | $max = $input->getOption('max'); 43 | $output->writeln(sprintf('Max items from this fetch is %d ', $max)); 44 | $items = []; 45 | 46 | try { 47 | $output->writeln(sprintf('Fetching from %d to %d', $offset, ($offset + $this->limit))); 48 | $response = $orderManager->rawFetch($offset, $this->limit); 49 | 50 | $paging = $response->get('paging'); 51 | $total = $paging['total']; 52 | $output->writeln(sprintf('Total: %d ', $total)); 53 | $this->displayTableResults($output, $response->get('results')); 54 | } catch (\Exception $exception) { 55 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 56 | } 57 | 58 | return 0; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Entity/Order/Payments/Payment.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Payments; 12 | 13 | use Gpupo\CommonSdk\Entity\EntityAbstract; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | 16 | class Payment extends EntityAbstract implements EntityInterface 17 | { 18 | /** 19 | * @codeCoverageIgnore 20 | */ 21 | public function getSchema(): array 22 | { 23 | return [ 24 | 'id' => 'integer', 25 | 'order_id' => 'integer', 26 | 'payer_id' => 'integer', 27 | 'collector' => 'object', 28 | 'currency_id' => 'string', 29 | 'status' => 'string', 30 | 'status_code' => 'string', 31 | 'status_detail' => 'string', 32 | 'transaction_amount' => 'number', 33 | 'shipping_cost' => 'number', 34 | 'overpaid_amount' => 'number', 35 | 'total_paid_amount' => 'number', 36 | 'marketplace_fee' => 'number', 37 | 'coupon_amount' => 'number', 38 | 'date_created' => 'datetime', 39 | 'date_last_modified' => 'datetime', 40 | 'card_id' => 'string', 41 | 'reason' => 'string', 42 | 'activation_uri' => 'string', 43 | 'payment_method_id' => 'string', 44 | 'installments' => 'integer', 45 | 'issuer_id' => 'integer', 46 | 'atm_transfer_reference' => 'object', 47 | 'coupon_id' => 'string', 48 | 'operation_type' => 'string', 49 | 'payment_type' => 'string', 50 | 'available_actions' => 'array', 51 | 'installment_amount' => 'number', 52 | 'deferred_period' => 'string', 53 | 'date_approved' => 'datetime', 54 | 'authorization_code' => 'string', 55 | 'transaction_order_id' => 'string', 56 | ]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/FactoryTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests; 12 | 13 | use Gpupo\CommonSdk\Tests\FactoryTestAbstract; 14 | use Gpupo\MercadolivreSdk\Client\Client; 15 | use Gpupo\MercadolivreSdk\Client\Ml; 16 | use Gpupo\MercadolivreSdk\Factory; 17 | 18 | /** 19 | * @coversNothing 20 | */ 21 | class FactoryTest extends FactoryTestAbstract 22 | { 23 | public $namespace = '\Gpupo\MercadolivreSdk\\'; 24 | 25 | public function getFactory() 26 | { 27 | return Factory::getInstance(); 28 | } 29 | 30 | /** 31 | * Dá acesso a ``Factory``. 32 | */ 33 | public function testSetClient() 34 | { 35 | $factory = new Factory(); 36 | 37 | $factory->setClient([ 38 | ]); 39 | 40 | $this->assertInstanceOf(Client::class, $factory->getClient()); 41 | } 42 | 43 | /** 44 | * Dá acesso a Sdk Oficial. 45 | */ 46 | public function testAccessMl() 47 | { 48 | $factory = new Factory(); 49 | 50 | $factory->setClient([]); 51 | 52 | $this->assertInstanceOf(Ml::class, $factory->getClient()->accessMl()); 53 | } 54 | 55 | /** 56 | * @dataProvider dataProviderManager 57 | * 58 | * @param mixed $objectExpected 59 | * @param mixed $target 60 | */ 61 | public function testCentralizaAcessoAManagers($objectExpected, $target) 62 | { 63 | return $this->assertInstanceOf( 64 | $objectExpected, 65 | $this->createObject($this->getFactory(), 'factoryManager', $target) 66 | ); 67 | } 68 | 69 | public function dataProviderObjetos() 70 | { 71 | return [ 72 | [$this->namespace.'Entity\Product\Product', 'product', null], 73 | ]; 74 | } 75 | 76 | public function dataProviderManager() 77 | { 78 | return [ 79 | [$this->namespace.'Entity\Product\Manager', 'product'], 80 | ]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/Entity/Message/MessageTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Message; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Message\From; 15 | use Gpupo\MercadolivreSdk\Entity\Message\Message; 16 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 17 | 18 | /** 19 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Message\Message 20 | */ 21 | class MessageTest extends TestCaseAbstract 22 | { 23 | use EntityTrait; 24 | 25 | public function dataProviderMessage() 26 | { 27 | $data = $this->getResourceJson('mockup/Message/item.json'); 28 | 29 | return $this->dataProviderEntitySchema(Message::class, $data); 30 | } 31 | 32 | /** 33 | * @testdox Possui método ``toCreation()`` para acessar o array usado na crianção de nova mensagem 34 | * 35 | * @param null|mixed $expected 36 | */ 37 | public function testToCreation() 38 | { 39 | $input = $this->getResourceJson('mockup/Message/creationRequest.json'); 40 | $message = $this->getFactory()->createMessage($input); 41 | $data = $message->toCreation(); 42 | $this->assertSame(['from', 'to', 'subject', 'text', 'attachments'], array_keys($data)); 43 | $this->assertIsArray($data['from']); 44 | $this->assertIsArray($data['to']); 45 | $this->assertCount(1, $data['to']); 46 | $this->assertIsArray($data['attachments']); 47 | $this->assertCount(0, $data['attachments']); 48 | } 49 | 50 | /** 51 | * @testdox Possui método ``getFrom()`` para acessar o objeto Remetente 52 | * @dataProvider dataProviderMessage 53 | * @cover ::get 54 | * @cover ::getSchema 55 | * @small 56 | * 57 | * @param null|mixed $expected 58 | */ 59 | public function testGetFrom(Message $message, $expected = null) 60 | { 61 | $this->assertInstanceOf(From::class, $message->getFrom()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Entity/Order/Payments/CollectorTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Payments; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Payments\Collector; 15 | use PHPUnit\Framework\TestCase as CoreTestCase; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Payments\Collector 19 | * 20 | * @method int getId() A $id acessor. 21 | * @method setId(integer $id) A $id setter 22 | */ 23 | class CollectorTest extends CoreTestCase 24 | { 25 | use EntityTrait; 26 | 27 | const QUALIFIED = Collector::class; 28 | 29 | public static function setUpBeforeClass(): void 30 | { 31 | static::setFullyQualifiedObject(self::QUALIFIED); 32 | parent::setUpBeforeClass(); 33 | } 34 | 35 | /** 36 | * @return Collector 37 | */ 38 | public function dataProviderCollector() 39 | { 40 | $expected = [ 41 | 'id' => 'integer', 42 | ]; 43 | 44 | return $this->dataProviderEntitySchema(self::QUALIFIED, $expected); 45 | } 46 | 47 | /** 48 | * @testdox Have a getter ``getId()`` to get ``Id`` 49 | * @dataProvider dataProviderCollector 50 | * @cover ::getId 51 | * @small 52 | * 53 | * @param Collector $collector Main Object 54 | * @param array $expected Fixture data 55 | */ 56 | public function testGetId(Collector $collector, array $expected) 57 | { 58 | $collector->setId($expected['id']); 59 | $this->assertSame($expected['id'], $collector->getId()); 60 | } 61 | 62 | /** 63 | * @testdox Have a setter ``setId()`` to set ``Id`` 64 | * @dataProvider dataProviderCollector 65 | * @cover ::setId 66 | * @small 67 | * 68 | * @param Collector $collector Main Object 69 | * @param array $expected Fixture data 70 | */ 71 | public function testSetId(Collector $collector, array $expected) 72 | { 73 | $collector->setId($expected['id']); 74 | $this->assertSame($expected['id'], $collector->getId()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Entity/Message/Manager.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Message; 12 | 13 | use Gpupo\CommonSdk\Traits\LoadTrait; 14 | use Gpupo\CommonSdk\Traits\TranslatorManagerTrait; 15 | use Gpupo\MercadolivreSdk\Entity\AbstractManager; 16 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 17 | 18 | final class Manager extends AbstractManager 19 | { 20 | use LoadTrait; 21 | use TranslatorManagerTrait; 22 | 23 | protected $entity = 'Message'; 24 | 25 | /** 26 | * @codeCoverageIgnore 27 | */ 28 | protected function setUp() 29 | { 30 | $this->maps = $this->loadArrayFromFile(__DIR__.'/map/restful.map.php'); 31 | } 32 | 33 | public function findByOrderId(Order $order): MessageCollection 34 | { 35 | $messages = new MessageCollection(); 36 | $offset = 0; 37 | 38 | do { 39 | $results = $this->fetchMessages($order->getId(), $offset); 40 | 41 | foreach ($results['results'] as $raw) { 42 | $message = new Message($raw); 43 | $messages->add($message); 44 | } 45 | 46 | $offset = $messages->count(); 47 | } while ($messages->count() !== $results['paging']['total']); 48 | 49 | return $messages; 50 | } 51 | 52 | public function create(Message $message): ?Message 53 | { 54 | $data = $message->toCreation(); 55 | $response = $this->execute($this->factoryMap('create'), json_encode($data)); 56 | 57 | if ($this->isHttpStatusCodeOK($response->getHttpStatusCode())) { 58 | return new Message($response->getData()->first()); 59 | } 60 | 61 | throw new \Exception(sprintf('Error #%d on creation', $response->getHttpStatusCode())); 62 | } 63 | 64 | protected function fetchMessages($itemId, $offset = 0, $limit = 50) 65 | { 66 | $responseJson = $this->perform($this->factoryMap('findByOrderId', [ 67 | 'itemId' => $itemId, 68 | 'offset' => $offset, 69 | 'limit' => $limit, 70 | ])); 71 | 72 | $results = $this->processResponse($responseJson); 73 | 74 | return $results; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Console/Command/Auth/TokenCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Auth; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputInterface; 15 | use Symfony\Component\Console\Output\OutputInterface; 16 | use Symfony\Component\Console\Question\ConfirmationQuestion; 17 | use Symfony\Component\Console\Question\Question; 18 | 19 | /** 20 | * @codeCoverageIgnore 21 | * 22 | * @see http://developers.mercadolibre.com/server-side/ 23 | */ 24 | final class TokenCommand extends AbstractCommand 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | protected function configure() 30 | { 31 | $this 32 | ->setName(self::NAME_PREFIX.'auth:token') 33 | ->setDescription('Get Mercado Livre token'); 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | protected function execute(InputInterface $input, OutputInterface $output) 40 | { 41 | $url = $this->getFactory()->getOptions()->get('app_url'); 42 | $client = $this->getFactory()->getClient(); 43 | 44 | try { 45 | $redirectUrl = $client->accessMl()->getAuthRedirectUrl($url); 46 | $question = new ConfirmationQuestion(sprintf('Open url %s in your browser? (y/n)', $redirectUrl), false); 47 | 48 | if ($this->getApplication()->getHelperSet()->get('question')->ask($input, $output, $question)) { 49 | exec("open ${redirectUrl}"); 50 | } 51 | 52 | $output->writeln('The authorization code is used to exchange it for the access_token.'); 53 | $question = new Question('code (starts with TG-): '); 54 | $code = $this->getApplication()->getHelperSet()->get('question')->ask($input, $output, $question); 55 | $response = $client->accessMl()->authorize($code, $url); 56 | $data = (array) $response['body']; 57 | 58 | return $this->saveCredentials($data, $output); 59 | } catch (\Exception $exception) { 60 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 61 | } 62 | 63 | return 0; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Entity/Order/Decorator/AbstractDecorator.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity\Order\Decorator; 12 | 13 | use Gpupo\Common\Entity\Collection; 14 | use Gpupo\CommonSdk\Traits\LoggerTrait; 15 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 16 | 17 | abstract class AbstractDecorator extends Collection 18 | { 19 | use LoggerTrait; 20 | 21 | protected $name = ''; 22 | 23 | public function setOrder(Order $order) 24 | { 25 | $this->set('order', $order); 26 | $this->initLogger($order->getLogger()); 27 | 28 | return $this; 29 | } 30 | 31 | public function getOrder() 32 | { 33 | return $this->get('order'); 34 | } 35 | 36 | public function setOriginalOrder($order) 37 | { 38 | $this->set('originalOrder', $order); 39 | 40 | return $this; 41 | } 42 | 43 | public function getOriginalOrder() 44 | { 45 | return $this->get('originalOrder'); 46 | } 47 | 48 | public function validate() 49 | { 50 | $order = $this->getOrder(); 51 | 52 | if (empty($order)) { 53 | $this->invalid('Order'); 54 | } 55 | 56 | $this->getOrder()->check(); 57 | 58 | return $this; 59 | } 60 | 61 | public function toArray(): array 62 | { 63 | try { 64 | $this->validate(); 65 | $array = $this->factoryArray(); 66 | } catch (\Exception $e) { 67 | return $this->fail($this->name.' ('.$e->getMessage().')'); 68 | } 69 | 70 | return $array; 71 | } 72 | 73 | protected function factoryArray() 74 | { 75 | throw new \InvalidArgumentException('factoryArray() deve ser sobrecarregado!'); 76 | } 77 | 78 | protected function fail($string = '') 79 | { 80 | $message = 'Order incomplete for status ['.$string.']'; 81 | $this->log('error', $message, [ 82 | 'order' => $this->getOrder(), 83 | ]); 84 | 85 | throw new \InvalidArgumentException($message); 86 | } 87 | 88 | protected function invalid($string = '') 89 | { 90 | $message = 'Attribute invalid: '.$string.' '; 91 | 92 | throw new \InvalidArgumentException($message); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Entity/AbstractManager.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Entity; 12 | 13 | use Gpupo\Common\Entity\CollectionInterface; 14 | use Gpupo\CommonSdk\Entity\EntityInterface; 15 | use Gpupo\CommonSdk\Entity\ManagerAbstract; 16 | use Gpupo\CommonSdk\Entity\ManagerInterface; 17 | 18 | abstract class AbstractManager extends ManagerAbstract implements ManagerInterface 19 | { 20 | public function factoryMap($operation, array $parameters = null) 21 | { 22 | $all = array_merge($this->fetchDefaultParameters(), (array) $parameters); 23 | 24 | return parent::factoryMap($operation, $all); 25 | } 26 | 27 | public function save(EntityInterface $entity, $route = 'save') 28 | { 29 | return $this->execute($this->factoryMap($route), $entity->toJson($route)); 30 | } 31 | 32 | public function findById($itemId): ?CollectionInterface 33 | { 34 | $data = parent::findById($itemId); 35 | 36 | if (empty($data) || 404 === $data->get('status')) { 37 | return null; 38 | } 39 | 40 | return $this->factoryEntity($data->toArray()); 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function update(EntityInterface $entity, EntityInterface $existent = null) 47 | { 48 | $text = 'Chamada a Atualização de entity '.$this->entity; 49 | 50 | return $this->log('debug', $text, [ 51 | 'entity' => $entity, 52 | 'existent' => $existent, 53 | ]); 54 | } 55 | 56 | public function isHttpStatusCodeOK($statusCode): bool 57 | { 58 | $intCode = (int) $statusCode; 59 | 60 | if (200 <= $statusCode && 300 > $statusCode) { 61 | return true; 62 | } 63 | 64 | return false; 65 | } 66 | 67 | protected function fetchDefaultParameters(): array 68 | { 69 | return (array) $this->getClient()->getOptions()->toArray(); 70 | } 71 | 72 | /** 73 | * {@inheritdoc} 74 | */ 75 | protected function fetchPrepare($data): ?CollectionInterface 76 | { 77 | if (empty($data)) { 78 | return null; 79 | } 80 | 81 | return $this->factoryEntityCollection($data); 82 | } 83 | 84 | protected function factoryEntityCollection($data): CollectionInterface 85 | { 86 | return $this->factoryNeighborObject($this->getEntityName().'Collection', $data); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Console/Command/Catalog/Product/ListCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Catalog\Product; 12 | 13 | use Gpupo\Common\Traits\TableTrait; 14 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 15 | use Symfony\Component\Console\Input\InputInterface; 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | class ListCommand extends AbstractCommand 19 | { 20 | use TableTrait; 21 | 22 | private $limit = 50; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this->setName(self::NAME_PREFIX.'catalog:product:list')->setDescription('Get the product list on Mercado Livre'); 30 | $this->addOptionsForList(); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | protected function execute(InputInterface $input, OutputInterface $output) 37 | { 38 | $productManager = $this->getFactory()->factoryManager('product'); 39 | $offset = $input->getOption('offset'); 40 | $max = $input->getOption('max'); 41 | $output->writeln(sprintf('Max items from this fetch is %d ', $max)); 42 | $items = []; 43 | 44 | try { 45 | $output->writeln(sprintf('Fetching from %d to %d', $offset, ($offset + $this->limit))); 46 | $response = $productManager->rawFetch($offset, $this->limit); 47 | $paging = $response->get('paging'); 48 | $total = $paging['total']; 49 | $output->writeln(sprintf('Total: %d ', $total)); 50 | $items = array_merge($items, $response->get('results')); 51 | while ($offset < ($total - $this->limit) && $offset < ($max - $this->limit)) { 52 | $offset += $this->limit; 53 | $output->writeln(sprintf('Fetching from %d to %d', $offset, ($offset + $this->limit))); 54 | $response = $productManager->rawFetch($offset, $this->limit); 55 | $items = array_merge($items, $response->get('results')); 56 | } 57 | 58 | $collection = []; 59 | 60 | foreach ($items as $item) { 61 | $collection[] = [ 62 | 'id' => $item, 63 | ]; 64 | } 65 | $this->displayTableResults($output, $collection); 66 | } catch (\Exception $exception) { 67 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 68 | } 69 | 70 | return 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Entity/Order/map/translate.native.map.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | $quantity = 0; 12 | $items = $native['order_items']; 13 | $acceptedOffer = []; 14 | foreach ($items as $item) { 15 | if (is_array($item)) { 16 | $quantity += $item['quantity']; 17 | $acceptedOffer[] = [ 18 | 'itemOffered' => [ 19 | 'sku' => $item['item']['id'], 20 | ], 21 | 'quantity' => $item['quantity'], 22 | 'price' => $item['unit_price'], 23 | ]; 24 | } 25 | } 26 | 27 | $dateTime = new DateTime($native['date_created']); 28 | 29 | $translateStatus = function ($status) { 30 | $string = mb_strtoupper($status); 31 | $list = include __DIR__.'/status.map.php'; 32 | $find = array_search($string, $list, true); 33 | 34 | return empty($find) ? $string : $find; 35 | }; 36 | 37 | return [ 38 | 'merchant' => [ 39 | 'name' => 'MERCADOLIVRE', 40 | 'marketplace' => 'MERCADOLIVRE', 41 | 'originNumber' => '', 42 | ], 43 | 'orderNumber' => $native->getId(), 44 | 'acceptedOffer' => $acceptedOffer, 45 | 'orderStatus' => $translateStatus($native->getStatus()), 46 | 'orderDate' => $dateTime->format('Y-m-d H:i:s'), 47 | 'customer' => [ 48 | 'document' => $native['buyer']['billing_info']['doc_number'], 49 | 'name' => $native['buyer']['first_name'].' '.$native['buyer']['last_name'], 50 | 'telephone' => '('.$native['buyer']['phone']['area_code'].') '.$native['buyer']['phone']['number'], 51 | 'email' => $native['buyer']['email'], 52 | ], 53 | 'billingAddress' => [ 54 | 'streetAddress' => $native->getShipping()['receiver_address']['street_name'], 55 | 'addressComplement' => $native->getShipping()['receiver_address']['comment'], 56 | 'addressReference' => '', 57 | 'addressNumber' => $native->getShipping()['receiver_address']['street_number'], 58 | 'addressLocality' => $native->getShipping()['receiver_address']['city']['name'], 59 | 'addressRegion' => str_replace('BR-', '', (string) $native->getShipping()['receiver_address']['state']['id']), 60 | 'addressNeighborhood' => '', 61 | 'postalCode' => $native->getShipping()['receiver_address']['zip_code'], 62 | ], 63 | 'currency' => 'BRL', 64 | 'price' => $native['total_amount'], 65 | 'discount' => 0, 66 | 'quantity' => $quantity, 67 | 'freight' => '', 68 | 'freightType' => (182 === (int) $native->getShipping()['shipping_option']['shipping_method_id']) ? 'EXPRESS' : 'NORMAL', 69 | 'total' => $native['total_amount'], 70 | ]; 71 | -------------------------------------------------------------------------------- /Resources/mockup/Order/item.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1068825849, 3 | "status": "paid", 4 | "status_detail": null, 5 | "date_created": "2013-05-27T10:01:50.000-04:00", 6 | "date_closed": "2013-05-27T10:04:07.000-04:00", 7 | "order_items": [ 8 | { 9 | "item": { 10 | "id": "MLB12345678", 11 | "title": "Samsung Galaxy", 12 | "variation_id": null, 13 | "variation_attributes": [] 14 | }, 15 | "quantity": 1, 16 | "unit_price": 499, 17 | "currency_id": "BRL" 18 | } 19 | ], 20 | "total_amount": 499, 21 | "currency_id": "BRL", 22 | "buyer": { 23 | "id": "123456789", 24 | "nickname": "COMPRADORTESTE", 25 | "email": "b@b.com", 26 | "phone": { 27 | "area_code": "11", 28 | "number": "12345678", 29 | "extension": null 30 | }, 31 | "first_name": "Comprador de testes", 32 | "last_name": "da Silva", 33 | "billing_info": { 34 | "doc_type": "CPF", 35 | "doc_number": "12345678910" 36 | } 37 | }, 38 | "seller": { 39 | "id": "123456789", 40 | "nickname": "VENDEDORTESTES", 41 | "email": "a@a.com", 42 | "phone": { 43 | "area_code": null, 44 | "number": "11 12345678", 45 | "extension": "11" 46 | }, 47 | "first_name": "Vendedor de Testes", 48 | "last_name": "testes de documentacao" 49 | }, 50 | "payments": [ 51 | { 52 | "id": "596707837", 53 | "transaction_amount": 499, 54 | "currency_id": "BRL", 55 | "status": "approved", 56 | "date_created": null, 57 | "date_last_modified": null 58 | } 59 | ], 60 | "feedback": { 61 | "purchase": null, 62 | "sale": null 63 | }, 64 | "shipping": { 65 | "id": 20676482441, 66 | "shipment_type": "shipping", 67 | "status": "pending", 68 | "shippingCode": "TR1234567891", 69 | "date_created": "2013-05-27T10:03:28.000-04:00", 70 | "receiver_address": { 71 | "id": 12345678, 72 | "street_number": "2055", 73 | "street_name": "Rua Lauro Linhares", 74 | "address_line": "Rua dos testes 123 ", 75 | "zip_code": "01001000", 76 | "city": { 77 | "id": "BR-SP-44", 78 | "name": "São Paulo" 79 | }, 80 | "state": { 81 | "id": "BR-SP", 82 | "name": "São Paulo" 83 | }, 84 | "country": { 85 | "id": "BR", 86 | "name": "Brasil" 87 | }, 88 | "latitude": null, 89 | "longitude": null, 90 | "comment": null 91 | }, 92 | "currency_id": "BRL", 93 | "cost": 0, 94 | "shipping_option": { 95 | "id": 2000880360030001, 96 | "shipping_method_id": 182, 97 | "name": "Expresso", 98 | "currency_id": "BRL", 99 | "cost": 14.9, 100 | "speed": { 101 | "shipping": null, 102 | "handling": null 103 | }, 104 | "estimated_delivery": { 105 | "date": null, 106 | "time_from": null, 107 | "time_to": null 108 | } 109 | } 110 | }, 111 | "tags": [ 112 | "paid", 113 | "not_delivered" 114 | ] 115 | } 116 | -------------------------------------------------------------------------------- /src/Console/Command/Auth/RefreshCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Console\Command\Auth; 12 | 13 | use Gpupo\MercadolivreSdk\Console\Command\AbstractCommand; 14 | use Symfony\Component\Console\Input\InputInterface; 15 | use Symfony\Component\Console\Output\OutputInterface; 16 | 17 | /** 18 | * @see http://developers.mercadolibre.com/server-side/ 19 | */ 20 | final class RefreshCommand extends AbstractCommand 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function configure() 26 | { 27 | $this 28 | ->setName(self::NAME_PREFIX.'auth:refresh') 29 | ->setDescription('Refresh Mercado Livre token') 30 | ->setHelp("What happens if I need to work with an access_token for more than 6 hours?\n"."If your app has the option offline_access selected, you will receive a refresh_token along with the access_token as shown before;\n".'you should save the refresh_token to be later exchanged for a new access_token upon expiration.'); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | protected function execute(InputInterface $input, OutputInterface $output) 37 | { 38 | $data = $this->getProjectData(); 39 | 40 | if (!\array_key_exists('refresh_token', $data)) { 41 | throw new \Exception('Refresh Token required!'); 42 | } 43 | 44 | $config = [ 45 | 'grant_type' => 'refresh_token', // It indicates that the intended operation is to refresh a token. 46 | 'client_id' => $this->getFactory()->getOptions()->get('client_id'), //The client ID of your application. 47 | 'client_secret' => $this->getFactory()->getOptions()->get('secret_key'), //The Secret Key generated for your app when created. 48 | 'refresh_token' => $data['refresh_token'], // The refresh token from the approval step. 49 | ]; 50 | 51 | foreach ($config as $key => $value) { 52 | if (empty($value)) { 53 | throw new \Exception(sprintf('%s is required!', $key)); 54 | } 55 | } 56 | 57 | $this->writeInfo($output, $config); 58 | $uri = $this->getFactory()->getClient()->getResourceUri('/oauth/token?'.http_build_query($config)); 59 | $output->writeln(sprintf('Request URL to perform is %s', $uri)); 60 | 61 | try { 62 | $response = $this->getFactory()->getClient()->post($uri, ''); 63 | $data = (array) $response['body']; 64 | 65 | return $this->saveCredentials($data, $output); 66 | } catch (\Exception $exception) { 67 | $output->writeln(sprintf('Error: %s', $exception->getmessage())); 68 | } 69 | 70 | return 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Client/Client.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Client; 12 | 13 | use Gpupo\CommonSchema\ArrayCollection\Application\API\OAuth\Client\AccessToken; 14 | use Gpupo\CommonSdk\Client\ClientAbstract; 15 | use Gpupo\CommonSdk\Client\ClientInterface; 16 | 17 | final class Client extends ClientAbstract implements ClientInterface 18 | { 19 | const ENDPOINT = 'api.mercadolibre.com'; 20 | 21 | const ACCEPT_DEFAULT = 'application/json'; 22 | 23 | private $ml; 24 | 25 | protected $header_access_token = true; 26 | 27 | public function accessMl() 28 | { 29 | if (empty($this->ml)) { 30 | $this->ml = new Ml( 31 | $this->getOptions()->get('client_id'), 32 | $this->getOptions()->get('secret_key'), 33 | $this->getOptions()->get('access_token'), 34 | $this->getOptions()->get('refresh_token') 35 | ); 36 | } 37 | 38 | return $this->ml; 39 | } 40 | 41 | protected function factoryTokenBodyParameters(): array 42 | { 43 | //Client Support 44 | $clientRefreshToken = $this->getOptions()->get('client_refresh_token'); 45 | if (!empty($clientRefreshToken)) { 46 | return [ 47 | 'grant_type' => 'refresh_token', 48 | 'client_id' => $this->getOptions()->get('client_id'), 49 | 'client_secret' => $this->getOptions()->get('client_secret'), 50 | 'refresh_token' => $clientRefreshToken, 51 | ]; 52 | } 53 | 54 | return [ 55 | 'grant_type' => 'client_credentials', 56 | 'client_id' => $this->getOptions()->get('client_id'), 57 | 'client_secret' => $this->getOptions()->get('client_secret'), 58 | ]; 59 | } 60 | 61 | public function requestToken() 62 | { 63 | $this->setMode('form'); 64 | $this->header_access_token = false; 65 | 66 | try { 67 | $request = $this->post($this->getOauthUrl('/token'), $this->factoryTokenBodyParameters()); 68 | } catch (\Exception $exception) { 69 | $this->header_access_token = true; 70 | throw $exception; 71 | } 72 | 73 | $this->header_access_token = true; 74 | $accessToken = $request->getData(AccessToken::class); 75 | 76 | return $accessToken; 77 | } 78 | 79 | protected function renderAuthorization(): array 80 | { 81 | if(false === $this->header_access_token) { 82 | return []; 83 | } 84 | 85 | return [ 86 | 'Authorization' => sprintf('Bearer %s', $this->getOptions()->get('access_token')), 87 | ]; 88 | } 89 | 90 | protected function getOauthUrl($path) 91 | { 92 | return $this->getOptions()->get('oauth_url').$path; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Bootstrap.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests; 12 | 13 | use Doctrine\ORM\EntityManager; 14 | use Doctrine\ORM\Tools\Setup; 15 | use Gpupo\CommonSchema\Normalizers\DoctrineTypesNormalizer; 16 | 17 | class Bootstrap 18 | { 19 | public static function factoryDoctrineEntityManager() 20 | { 21 | $commonSchemaPath = __DIR__.'/../vendor/gpupo/common-schema/src'; 22 | 23 | DoctrineTypesNormalizer::overrideTypes(); 24 | $evm = new \Doctrine\Common\EventManager(); 25 | $cache = new \Doctrine\Common\Cache\ArrayCache(); 26 | $annotationReader = new \Doctrine\Common\Annotations\AnnotationReader(); 27 | $cachedAnnotationReader = new \Doctrine\Common\Annotations\CachedReader($annotationReader, $cache); 28 | $driverChain = new \Doctrine\ORM\Mapping\Driver\DriverChain(); 29 | // \Gedmo\DoctrineExtensions::registerAbstractMappingIntoDriverChainORM($driverChain, $cachedAnnotationReader); 30 | $annotationDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($cachedAnnotationReader, [$commonSchemaPath]); 31 | $driverChain->addDriver($annotationDriver, 'Entity'); 32 | // general ORM configuration 33 | $config = new \Doctrine\ORM\Configuration(); 34 | $config->setProxyDir(sys_get_temp_dir()); 35 | $config->setProxyNamespace('Proxy'); 36 | $config->setAutoGenerateProxyClasses(false); // this can be based on production config. 37 | // register metadata driver 38 | $config->setMetadataDriverImpl($driverChain); 39 | // use our already initialized cache driver 40 | $config->setMetadataCacheImpl($cache); 41 | $config->setQueryCacheImpl($cache); 42 | // loggable, not used in example 43 | // $loggableListener = new \Gedmo\Loggable\LoggableListener(); 44 | // $loggableListener->setAnnotationReader($cachedAnnotationReader); 45 | // $evm->addEventSubscriber($loggableListener); 46 | 47 | //SQL log 48 | // $logger = new \Doctrine\DBAL\Logging\EchoSQLLogger(); 49 | // $config->setSQLLogger($logger); 50 | 51 | // timestampable 52 | // $timestampableListener = new \Gedmo\Timestampable\TimestampableListener(); 53 | // $timestampableListener->setAnnotationReader($cachedAnnotationReader); 54 | // $evm->addEventSubscriber($timestampableListener); 55 | $config = Setup::createAnnotationMetadataConfiguration([$commonSchemaPath], true, null, null, false); 56 | $connectionParams = [ 57 | 'dbname' => 'app', 58 | 'user' => 'app_db_user', 59 | 'password' => 'app8as3', 60 | 'host' => getenv('dbhost'), 61 | 'driver' => 'pdo_mysql', 62 | ]; 63 | $entityManager = EntityManager::create($connectionParams, $config, $evm); 64 | 65 | return $entityManager; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/Entity/Order/TranslatorTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order; 12 | 13 | use Gpupo\CommonSchema\TranslatorDataCollection; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 15 | use Gpupo\MercadolivreSdk\Entity\Order\Translator; 16 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 17 | 18 | /** 19 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Translator 20 | */ 21 | class TranslatorTest extends TestCaseAbstract 22 | { 23 | /** 24 | * @return \Gpupo\MercadolivreSdk\Entity\Order\Translator 25 | */ 26 | public function dataProviderTranslator() 27 | { 28 | $list = []; 29 | 30 | foreach ($this->providerOrders() as $order) { 31 | $translator = new Translator(['native' => $order]); 32 | 33 | $list[] = [$translator]; 34 | } 35 | 36 | return $list; 37 | } 38 | 39 | /** 40 | * @testdox Falha ao tentar traduzir para extrangeiro sem possuir nativo 41 | * @covers ::translateFrom 42 | */ 43 | public function testLoadMapFailForeign() 44 | { 45 | $this->expectException(\Gpupo\CommonSchema\TranslatorException::class); 46 | $this->expectExceptionMessage('Foreign object missed!'); 47 | 48 | $t = new Translator(); 49 | $t->import(); 50 | } 51 | 52 | /** 53 | * @testdox Falha ao tentar traduzir para nativo sem possuir estrangeiro 54 | * @covers ::translateTo 55 | */ 56 | public function testLoadMapFailNative() 57 | { 58 | $this->expectException(\Gpupo\CommonSchema\TranslatorException::class); 59 | $this->expectExceptionMessage('Order missed!'); 60 | 61 | $t = new Translator(); 62 | $t->export(); 63 | } 64 | 65 | /** 66 | * @testdox Usa o método ``export()`` para converter o pedido em schema comum em pedido Mercado Livre 67 | * @cover ::translateTo 68 | * @dataProvider dataProviderTranslator 69 | */ 70 | public function testTranslateTo(Translator $translator) 71 | { 72 | $translated = $translator->export(); 73 | $this->assertInstanceOf(TranslatorDataCollection::class, $translated); 74 | $this->assertIsArray($translated->toArray(), 'internal type'); 75 | } 76 | 77 | /** 78 | * @testdox Usa o método ``import()`` para traduzir o pedido schema comum em Mercado Livre 79 | * @cover ::translateFrom 80 | * @dataProvider dataProviderTranslator 81 | */ 82 | public function testTranslateFrom(Translator $translator) 83 | { 84 | $foreign = $translator->export(); 85 | $this->assertInstanceOf(TranslatorDataCollection::class, $foreign); 86 | $translator->setForeign($foreign); 87 | $translated = $translator->import(); 88 | $this->assertInstanceOf(Order::class, $translated); 89 | $this->assertIsArray($translated->toArray(), 'internal type'); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Resources/mockup/Product/day_visits.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "item_id": "MCO471870973", 4 | "date_from": "2018-08-07T00:00:00Z", 5 | "date_to": "2018-08-10T00:00:00Z", 6 | "total_visits": 15, 7 | "last": 3, 8 | "unit": "day", 9 | "results": [ 10 | { 11 | "date": "2018-08-07T00:00:00Z", 12 | "total": 8, 13 | "visits_detail": [ 14 | { 15 | "company": "mercadolibre", 16 | "quantity": 8 17 | } 18 | ] 19 | }, 20 | { 21 | "date": "2018-08-08T00:00:00Z", 22 | "total": 1, 23 | "visits_detail": [ 24 | { 25 | "company": "mercadolibre", 26 | "quantity": 1 27 | } 28 | ] 29 | }, 30 | { 31 | "date": "2018-08-09T00:00:00Z", 32 | "total": 6, 33 | "visits_detail": [ 34 | { 35 | "company": "mercadolibre", 36 | "quantity": 6 37 | } 38 | ] 39 | } 40 | ] 41 | }, 42 | { 43 | "item_id": "MCO473861358", 44 | "date_from": "2018-08-07T00:00:00Z", 45 | "date_to": "2018-08-10T00:00:00Z", 46 | "total_visits": 21, 47 | "last": 3, 48 | "unit": "day", 49 | "results": [ 50 | { 51 | "date": "2018-08-07T00:00:00Z", 52 | "total": 12, 53 | "visits_detail": [ 54 | { 55 | "company": "mercadolibre", 56 | "quantity": 12 57 | } 58 | ] 59 | }, 60 | { 61 | "date": "2018-08-08T00:00:00Z", 62 | "total": 1, 63 | "visits_detail": [ 64 | { 65 | "company": "mercadolibre", 66 | "quantity": 1 67 | } 68 | ] 69 | }, 70 | { 71 | "date": "2018-08-09T00:00:00Z", 72 | "total": 8, 73 | "visits_detail": [ 74 | { 75 | "company": "mercadolibre", 76 | "quantity": 8 77 | } 78 | ] 79 | } 80 | ] 81 | }, 82 | { 83 | "item_id": "MCO472253403", 84 | "date_from": "2018-08-07T00:00:00Z", 85 | "date_to": "2018-08-10T00:00:00Z", 86 | "total_visits": 12, 87 | "last": 3, 88 | "unit": "day", 89 | "results": [ 90 | { 91 | "date": "2018-08-07T00:00:00Z", 92 | "total": 9, 93 | "visits_detail": [ 94 | { 95 | "company": "mercadolibre", 96 | "quantity": 9 97 | } 98 | ] 99 | }, 100 | { 101 | "date": "2018-08-08T00:00:00Z", 102 | "total": 1, 103 | "visits_detail": [ 104 | { 105 | "company": "mercadolibre", 106 | "quantity": 1 107 | } 108 | ] 109 | }, 110 | { 111 | "date": "2018-08-09T00:00:00Z", 112 | "total": 2, 113 | "visits_detail": [ 114 | { 115 | "company": "mercadolibre", 116 | "quantity": 2 117 | } 118 | ] 119 | } 120 | ] 121 | } 122 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mercadolivre-SDK 2 | 3 | SDK Não Oficial para integração a partir de aplicações PHP com as APIs Mercadolivre 4 | 5 | [![Build Status](https://secure.travis-ci.org/gpupo/mercadolivre-sdk.png?branch=main)](http://travis-ci.org/gpupo/mercadolivre-sdk) 6 | 7 | ## Requisitos para uso 8 | 9 | * PHP *>=8.0* 10 | * [curl extension](http://php.net/manual/en/intro.curl.php) 11 | * [Composer Dependency Manager](http://getcomposer.org) 12 | 13 | A versão atual deste pacote funciona apenas em [versões de PHP atualmente suportadas](http://php.net/supported-versions.php). 14 | 15 | Este componente **não é uma aplicação Stand Alone** e seu objetivo é ser utilizado como biblioteca. 16 | Sua implantação deve ser feita por desenvolvedores experientes. **Isto não é um Plugin!** 17 | 18 | As opções que funcionam no modo de comando apenas servem para depuração em modo de 19 | desenvolvimento. 20 | 21 | A documentação mais importante está nos testes unitários. Se você não consegue ler os testes unitários, eu recomendo que não utilize esta biblioteca. 22 | 23 | ## Direitos autorais e de licença 24 | 25 | Este componente está sob a [licença MIT](https://github.com/gpupo/common-sdk/blob/master/LICENSE). Para a informação dos direitos autorais e de licença você deve ler o arquivo de [licença](https://github.com/gpupo/common-sdk/blob/master/LICENSE) que é distribuído com este código-fonte. 26 | 27 | ### Resumo da licença 28 | 29 | Exigido: 30 | 31 | - Aviso de licença e direitos autorais 32 | 33 | Permitido: 34 | 35 | - Uso comercial 36 | - Modificação 37 | - Distribuição 38 | - Sublicenciamento 39 | 40 | Proibido: 41 | 42 | - Responsabilidade Assegurada 43 | 44 | ## Agradecimentos 45 | 46 | * A todos os que [contribuiram com patchs](https://github.com/gpupo/mercadolivre-sdk/contributors); 47 | * Aos que [fizeram sugestões importantes](https://github.com/gpupo/mercadolivre-sdk/issues); 48 | * Aos desenvolvedores que criaram as [bibliotecas utilizadas neste componente](https://github.com/gpupo/mercadolivre-sdk/blob/master/Resources/doc/libraries-list.md). 49 | 50 | _- [Gilmar Pupo](https://opensource.gpupo.com/)_ 51 | 52 | 53 | ## Instalação 54 | 55 | Adicione o pacote ``mercadolivre-sdk`` ao seu projeto utilizando [composer](http://getcomposer.org): 56 | 57 | composer require gpupo/mercadolivre-sdk 58 | 59 | ## Uso 60 | 61 | 62 | 63 | ## Links 64 | 65 | * [Mercadolivre-sdk Composer Package](https://packagist.org/packages/gpupo/mercadolivre-sdk) no packagist.org 66 | * [Documentação Oficial](http://developers.mercadolivre.com.br/) 67 | * [Lista de apps em sua conta Mercado Livre](https://developers.mercadolivre.com.br/apps/home/) 68 | * [SDK Oficial](https://github.com/mercadolivre/marketplace-api-sdk-php) 69 | * [Marketplace-bundle Composer Package](https://opensource.gpupo.com/MarkethubBundle/) - Integração deste pacote com Symfony 70 | * [Outras SDKs para o Ecommerce do Brasil](https://opensource.gpupo.com/common-sdk/) 71 | * [Github Repository](https://github.com/gpupo/mercadolivre-sdk/); 72 | 73 | 74 | ## Desenvolvimento 75 | 76 | git clone --depth=1 git@github.com:gpupo/mercadolivre-sdk.git 77 | cd mercadolivre-sdk; 78 | ant; 79 | 80 | Personalize a configuração do ``phpunit``: 81 | 82 | cp phpunit.xml.dist phpunit.xml; 83 | 84 | Personalize os parâmetros! 85 | 86 | 87 | *Dica*: Verifique os logs gerados em ``var/log/main.log`` 88 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | # Mercadolivre-SDK 5 | 6 | SDK Não Oficial para integração a partir de aplicações PHP com as APIs Mercadolivre 7 | 8 | [![Build Status](https://secure.travis-ci.org/gpupo/mercadolivre-sdk.png?branch=main)](http://travis-ci.org/gpupo/mercadolivre-sdk) 9 | 10 | ## Requisitos para uso 11 | 12 | * PHP *>=8.0* 13 | * [curl extension](http://php.net/manual/en/intro.curl.php) 14 | * [Composer Dependency Manager](http://getcomposer.org) 15 | 16 | A versão atual deste pacote funciona apenas em [versões de PHP atualmente suportadas](http://php.net/supported-versions.php). 17 | 18 | Este componente **não é uma aplicação Stand Alone** e seu objetivo é ser utilizado como biblioteca. 19 | Sua implantação deve ser feita por desenvolvedores experientes. **Isto não é um Plugin!** 20 | 21 | As opções que funcionam no modo de comando apenas servem para depuração em modo de 22 | desenvolvimento. 23 | 24 | A documentação mais importante está nos testes unitários. Se você não consegue ler os testes unitários, eu recomendo que não utilize esta biblioteca. 25 | 26 | ## Direitos autorais e de licença 27 | 28 | Este componente está sob a [licença MIT](https://github.com/gpupo/common-sdk/blob/master/LICENSE). Para a informação dos direitos autorais e de licença você deve ler o arquivo de [licença](https://github.com/gpupo/common-sdk/blob/master/LICENSE) que é distribuído com este código-fonte. 29 | 30 | ### Resumo da licença 31 | 32 | Exigido: 33 | 34 | - Aviso de licença e direitos autorais 35 | 36 | Permitido: 37 | 38 | - Uso comercial 39 | - Modificação 40 | - Distribuição 41 | - Sublicenciamento 42 | 43 | Proibido: 44 | 45 | - Responsabilidade Assegurada 46 | 47 | ## Agradecimentos 48 | 49 | * A todos os que [contribuiram com patchs](https://github.com/gpupo/mercadolivre-sdk/contributors); 50 | * Aos que [fizeram sugestões importantes](https://github.com/gpupo/mercadolivre-sdk/issues); 51 | * Aos desenvolvedores que criaram as [bibliotecas utilizadas neste componente](https://github.com/gpupo/mercadolivre-sdk/blob/master/Resources/doc/libraries-list.md). 52 | 53 | _- [Gilmar Pupo](https://opensource.gpupo.com/)_ 54 | 55 | 56 | ## Instalação 57 | 58 | Adicione o pacote ``mercadolivre-sdk`` ao seu projeto utilizando [composer](http://getcomposer.org): 59 | 60 | composer require gpupo/mercadolivre-sdk 61 | 62 | ## Uso 63 | 64 | 65 | 66 | ## Links 67 | 68 | * [Mercadolivre-sdk Composer Package](https://packagist.org/packages/gpupo/mercadolivre-sdk) no packagist.org 69 | * [Documentação Oficial](http://developers.mercadolivre.com.br/) 70 | * [Lista de apps em sua conta Mercado Livre](https://developers.mercadolivre.com.br/apps/home/) 71 | * [SDK Oficial](https://github.com/mercadolivre/marketplace-api-sdk-php) 72 | * [Marketplace-bundle Composer Package](https://opensource.gpupo.com/MarkethubBundle/) - Integração deste pacote com Symfony 73 | * [Outras SDKs para o Ecommerce do Brasil](https://opensource.gpupo.com/common-sdk/) 74 | * [Github Repository](https://github.com/gpupo/mercadolivre-sdk/); 75 | 76 | 77 | ## Desenvolvimento 78 | 79 | git clone --depth=1 git@github.com:gpupo/mercadolivre-sdk.git 80 | cd mercadolivre-sdk; 81 | ant; 82 | 83 | Personalize a configuração do ``phpunit``: 84 | 85 | cp phpunit.xml.dist phpunit.xml; 86 | 87 | Personalize os parâmetros! 88 | 89 | 90 | *Dica*: Verifique os logs gerados em ``var/log/main.log`` 91 | -------------------------------------------------------------------------------- /tests/TestCaseAbstract.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests; 12 | 13 | use Gpupo\CommonSdk\Tests\TestCaseAbstract as CommonSdkTestCaseAbstract; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 15 | use Gpupo\MercadolivreSdk\Entity\Product\Product; 16 | use Gpupo\MercadolivreSdk\Factory; 17 | 18 | abstract class TestCaseAbstract extends CommonSdkTestCaseAbstract 19 | { 20 | private $factory; 21 | 22 | public static function getResourcesPath() 23 | { 24 | return \dirname(__DIR__).'/Resources/'; 25 | } 26 | 27 | public function factoryClient() 28 | { 29 | return $this->getFactory()->getClient(); 30 | } 31 | 32 | public function providerProducts() 33 | { 34 | $manager = $this->getFactory()->factoryManager('product'); 35 | $manager->setDryRun($this->factoryResponseFromFixture('mockup/Product/list.json')); 36 | 37 | return $manager->fetch(); 38 | } 39 | 40 | public function dataProviderProducts() 41 | { 42 | $list = []; 43 | 44 | foreach ($this->providerProducts() as $product) { 45 | if (!is_a($product, Product::class)) { 46 | throw new \InvalidArgumentException(sprintf('$product must be a mercadolivre-sdk entity! [%s] received', \get_class($product))); 47 | } 48 | $list[] = [$product]; 49 | } 50 | 51 | return $list; 52 | } 53 | 54 | public function providerOrders() 55 | { 56 | $manager = $this->getFactory()->factoryManager('order'); 57 | $manager->setDryRun($this->factoryResponseFromFixture('mockup/Order/list.json')); 58 | 59 | return $manager->fetch(); 60 | } 61 | 62 | public function dataProviderOrders() 63 | { 64 | $list = []; 65 | 66 | foreach ($this->providerOrders() as $order) { 67 | if (!is_a($order, Order::class)) { 68 | throw new \InvalidArgumentException(sprintf('$product must be a mercadolivre-sdk entity! [%s] received', \get_class($order))); 69 | } 70 | $list[] = [$order]; 71 | } 72 | 73 | return $list; 74 | } 75 | 76 | protected function getOptions() 77 | { 78 | return [ 79 | 'app_id' => $this->getConstant('APP_ID'), 80 | 'secret_key' => $this->getConstant('SECRET_KEY'), 81 | 'access_token' => $this->getConstant('ACCESS_TOKEN'), 82 | 'verbose' => $this->getConstant('VERBOSE'), 83 | 'dryrun' => $this->getConstant('DRYRUN'), 84 | 'registerPath' => $this->getConstant('REGISTER_PATH'), 85 | ]; 86 | } 87 | 88 | protected function getFactory() 89 | { 90 | if (!$this->factory) { 91 | $this->factory = Factory::getInstance()->setup($this->getOptions(), $this->getLogger()); 92 | } 93 | 94 | return $this->factory; 95 | } 96 | 97 | /** 98 | * Requer Implementação mas não será abstrato para não impedir testes que não o usam. 99 | * 100 | * @param null|mixed $filename 101 | */ 102 | protected function getManager($filename = null) 103 | { 104 | unset($filename); 105 | } 106 | 107 | protected function hasToken() 108 | { 109 | return $this->hasConstant('SECRET_KEY'); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/Entity/Order/Buyer/BillingInfoTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Buyer; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Buyer\BillingInfo; 15 | use PHPUnit\Framework\TestCase as CoreTestCase; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Buyer\BillingInfo 19 | */ 20 | class BillingInfoTest extends CoreTestCase 21 | { 22 | use EntityTrait; 23 | 24 | const QUALIFIED = BillingInfo::class; 25 | 26 | public static function setUpBeforeClass(): void 27 | { 28 | static::setFullyQualifiedObject(self::QUALIFIED); 29 | parent::setUpBeforeClass(); 30 | } 31 | 32 | /** 33 | * @return BillingInfo 34 | */ 35 | public function dataProviderBillingInfo() 36 | { 37 | $expected = [ 38 | 'doc_type' => 'string', 39 | 'doc_number' => 'string', 40 | ]; 41 | 42 | return $this->dataProviderEntitySchema(self::QUALIFIED, $expected); 43 | } 44 | 45 | /** 46 | * @testdox Have a getter ``getDocType()`` to get ``DocType`` 47 | * @dataProvider dataProviderBillingInfo 48 | * @cover ::getDocType 49 | * @small 50 | * 51 | * @param BillingInfo $billingInfo Main Object 52 | * @param array $expected Fixture data 53 | */ 54 | public function testGetDocType(BillingInfo $billingInfo, array $expected) 55 | { 56 | $billingInfo->setDocType($expected['doc_type']); 57 | $this->assertSame($expected['doc_type'], $billingInfo->getDocType()); 58 | } 59 | 60 | /** 61 | * @testdox Have a setter ``setDocType()`` to set ``DocType`` 62 | * @dataProvider dataProviderBillingInfo 63 | * @cover ::setDocType 64 | * @small 65 | * 66 | * @param BillingInfo $billingInfo Main Object 67 | * @param array $expected Fixture data 68 | */ 69 | public function testSetDocType(BillingInfo $billingInfo, array $expected) 70 | { 71 | $billingInfo->setDocType($expected['doc_type']); 72 | $this->assertSame($expected['doc_type'], $billingInfo->getDocType()); 73 | } 74 | 75 | /** 76 | * @testdox Have a getter ``getDocNumber()`` to get ``DocNumber`` 77 | * @dataProvider dataProviderBillingInfo 78 | * @cover ::getDocNumber 79 | * @small 80 | * 81 | * @param BillingInfo $billingInfo Main Object 82 | * @param array $expected Fixture data 83 | */ 84 | public function testGetDocNumber(BillingInfo $billingInfo, array $expected) 85 | { 86 | $billingInfo->setDocNumber($expected['doc_number']); 87 | $this->assertSame($expected['doc_number'], $billingInfo->getDocNumber()); 88 | } 89 | 90 | /** 91 | * @testdox Have a setter ``setDocNumber()`` to set ``DocNumber`` 92 | * @dataProvider dataProviderBillingInfo 93 | * @cover ::setDocNumber 94 | * @small 95 | * 96 | * @param BillingInfo $billingInfo Main Object 97 | * @param array $expected Fixture data 98 | */ 99 | public function testSetDocNumber(BillingInfo $billingInfo, array $expected) 100 | { 101 | $billingInfo->setDocNumber($expected['doc_number']); 102 | $this->assertSame($expected['doc_number'], $billingInfo->getDocNumber()); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /tests/Entity/Order/Shipping/SpeedTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Shipping\Speed; 15 | use PHPUnit\Framework\TestCase as CoreTestCase; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Shipping\Speed 19 | * 20 | * @method string getHandling() A $handling acessor. 21 | * @method setHandling(string $handling) A $handling setter 22 | * @method string getShipping() A $shipping acessor. 23 | * @method setShipping(string $shipping) A $shipping setter 24 | */ 25 | class SpeedTest extends CoreTestCase 26 | { 27 | use EntityTrait; 28 | 29 | const QUALIFIED = Speed::class; 30 | 31 | public static function setUpBeforeClass(): void 32 | { 33 | static::setFullyQualifiedObject(self::QUALIFIED); 34 | parent::setUpBeforeClass(); 35 | } 36 | 37 | /** 38 | * @return Speed 39 | */ 40 | public function dataProviderSpeed() 41 | { 42 | $expected = [ 43 | 'handling' => 'string', 44 | 'shipping' => 'string', 45 | ]; 46 | 47 | return $this->dataProviderEntitySchema(self::QUALIFIED, $expected); 48 | } 49 | 50 | /** 51 | * @testdox Have a getter ``getHandling()`` to get ``Handling`` 52 | * @dataProvider dataProviderSpeed 53 | * @cover ::getHandling 54 | * @small 55 | * 56 | * @param Speed $speed Main Object 57 | * @param array $expected Fixture data 58 | */ 59 | public function testGetHandling(Speed $speed, array $expected) 60 | { 61 | $speed->setHandling($expected['handling']); 62 | $this->assertSame($expected['handling'], $speed->getHandling()); 63 | } 64 | 65 | /** 66 | * @testdox Have a setter ``setHandling()`` to set ``Handling`` 67 | * @dataProvider dataProviderSpeed 68 | * @cover ::setHandling 69 | * @small 70 | * 71 | * @param Speed $speed Main Object 72 | * @param array $expected Fixture data 73 | */ 74 | public function testSetHandling(Speed $speed, array $expected) 75 | { 76 | $speed->setHandling($expected['handling']); 77 | $this->assertSame($expected['handling'], $speed->getHandling()); 78 | } 79 | 80 | /** 81 | * @testdox Have a getter ``getShipping()`` to get ``Shipping`` 82 | * @dataProvider dataProviderSpeed 83 | * @cover ::getShipping 84 | * @small 85 | * 86 | * @param Speed $speed Main Object 87 | * @param array $expected Fixture data 88 | */ 89 | public function testGetShipping(Speed $speed, array $expected) 90 | { 91 | $speed->setShipping($expected['shipping']); 92 | $this->assertSame($expected['shipping'], $speed->getShipping()); 93 | } 94 | 95 | /** 96 | * @testdox Have a setter ``setShipping()`` to set ``Shipping`` 97 | * @dataProvider dataProviderSpeed 98 | * @cover ::setShipping 99 | * @small 100 | * 101 | * @param Speed $speed Main Object 102 | * @param array $expected Fixture data 103 | */ 104 | public function testSetShipping(Speed $speed, array $expected) 105 | { 106 | $speed->setShipping($expected['shipping']); 107 | $this->assertSame($expected['shipping'], $speed->getShipping()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Resources/mockup/Message/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "paging": { 3 | "limit": 2, 4 | "offset": 1, 5 | "total": 270 6 | }, 7 | "results": [ 8 | { 9 | "_id": "43b450d6bd3f47fb94394041b26c519f", 10 | "message_id": "43b450d6bd3f47fb94394041b26c519f", 11 | "date_received": "2016-11-07T15:03:14.978Z", 12 | "date": "2016-11-07T15:03:14.978Z", 13 | "date_available": "2016-11-07T15:03:14.978Z", 14 | "date_notified": "2016-11-07T15:05:50.179Z", 15 | "date_read": "2016-11-08T22:43:17.767Z", 16 | "from": { 17 | "user_id": "76601286", 18 | "email": "mailfrom.3fd70y+2-ogeytenjqgi3tombx@mail.mercadolibre.com", 19 | "name": null 20 | }, 21 | "to": [ 22 | { 23 | "user_id": "106459677", 24 | "email": "mailto.lj36rj8+2-ogeytenjqgi3tomjw@test.mercadolibre.com" 25 | } 26 | ], 27 | "subject": null, 28 | "text": { 29 | "plain": "Mensaje de pruebas desde api publica con attachment. Multiples 'to' " 30 | }, 31 | "attachments": [ 32 | { 33 | "size": "103584", 34 | "type": "image/png", 35 | "date": "Tue, 25 Oct 2016 22:56:47 GMT", 36 | "filename": "76601286_51a2e39b-7ff6-48ef-85f8-3025676db43e.png", 37 | "original_filename": "Captura de pantalla 2016-10-20 a las 2.26.09 p.m..png" 38 | } 39 | ], 40 | "attachments_validations": null, 41 | "headers": null, 42 | "site_id": "MLA", 43 | "resource": "orders", 44 | "resource_id": "1125027671", 45 | "status": "available", 46 | "moderation_status": "non_moderated", 47 | "moderation": { 48 | "status": "non_moderated" 49 | }, 50 | "client_id": 1000 51 | }, 52 | { 53 | "_id": "37befd545a2d436f89e672b33990ef8b", 54 | "message_id": "37befd545a2d436f89e672b33990ef8b", 55 | "date_received": "2016-11-07T14:56:02.500Z", 56 | "date": "2016-11-07T14:56:02.500Z", 57 | "date_available": "2016-11-07T14:56:02.500Z", 58 | "date_notified": "2016-11-07T14:57:46.659Z", 59 | "date_read": "2016-11-07T15:19:08.967Z", 60 | "from": { 61 | "user_id": "76601286", 62 | "email": "mailfrom.3fd70y+2-ogeytenjqgi3tombx@mail.mercadolibre.com", 63 | "name": null 64 | }, 65 | "to": [ 66 | { 67 | "user_id": "106459677", 68 | "email": "mailto.lj36rj8+2-ogeytenjqgi3tomjw@test.mercadolibre.com" 69 | } 70 | ], 71 | "subject": null, 72 | "text": { 73 | "plain": "Mensaje de pruebas desde api publica con attachment. Multiples 'to' " 74 | }, 75 | "attachments": [ 76 | { 77 | "size": "103584", 78 | "type": "image/png", 79 | "date": "Tue, 25 Oct 2016 22:56:47 GMT", 80 | "filename": "76601286_51a2e39b-7ff6-48ef-85f8-3025676db43e.png", 81 | "original_filename": "Captura de pantalla 2016-10-20 a las 2.26.09 p.m..png" 82 | } 83 | ], 84 | "attachments_validations": null, 85 | "headers": null, 86 | "site_id": "MLA", 87 | "resource": "orders", 88 | "resource_id": "1125027671", 89 | "status": "available", 90 | "moderation_status": "non_moderated", 91 | "moderation": { 92 | "status": "non_moderated" 93 | }, 94 | "client_id": 1000 95 | } 96 | ] 97 | } 98 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | {% comment %} 3 | Parameters List: 4 | https://help.github.com/articles/repository-metadata-on-github-pages/ 5 | {% endcomment %} 6 | 7 | 8 | 9 | 10 | 11 | Project {{ site.github.project_title }} by @{{ site.github.owner_name }} 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

{{ site.github.project_title }}

35 |

{{ site.github.project_tagline }}

36 |
37 | 47 |
48 | 51 |
52 | {{ content }} 53 |
54 | 67 |
68 | 69 |
70 |
71 |
72 | 73 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Resources/schema/order.yaml: -------------------------------------------------------------------------------- 1 | id: integer 2 | status: string 3 | status_detail: 4 | code: string 5 | description: string 6 | date_created: string 7 | date_closed: string 8 | order_items: 9 | - 10 | id: string 11 | title: string 12 | category_id: string 13 | variation_id: string 14 | quantity: integer 15 | unit_price: number 16 | currency_id: string 17 | sale_fee: number 18 | condition: string 19 | warranty: string 20 | seller_custom_field: string 21 | variation_attributes: array 22 | differential_pricing_id: integer 23 | listing_type_id: string 24 | base_currency_id: string 25 | full_unit_price: number 26 | base_exchange_rate: number 27 | manufacturing_days: integer 28 | total_amount: number 29 | currency_id: string 30 | buyer: 31 | id: integer 32 | nickname: string 33 | email: string 34 | phone: 35 | area_code: integer 36 | extension: string 37 | number: string 38 | verified: bool 39 | alternative_phone: 40 | area_code: integer 41 | extension: string 42 | number: string 43 | verified: bool 44 | first_name: string 45 | last_name: string 46 | billing_info: 47 | doc_type: string 48 | doc_number: string 49 | seller: 50 | id: integer 51 | nickname: string 52 | email: string 53 | phone: 54 | area_code: integer 55 | extension: string 56 | number: string 57 | verified: bool 58 | alternative_phone: 59 | area_code: integer 60 | extension: string 61 | number: string 62 | verified: bool 63 | first_name: string 64 | last_name: string 65 | payments: 66 | - 67 | id: integer 68 | order_id: integer 69 | payer_id: integer 70 | collector: 71 | id: integer 72 | currency_id: string 73 | status: string 74 | status_code: string 75 | status_detail: string 76 | transaction_amount: number 77 | shipping_cost: number 78 | overpaid_amount: number 79 | total_paid_amount: number 80 | marketplace_fee: number 81 | coupon_amount: number 82 | date_created: datetime 83 | date_last_modified: datetime 84 | card_id: string 85 | reason: string 86 | activation_uri: string 87 | payment_method_id: string 88 | installments: integer 89 | issuer_id: integer 90 | atm_transfer_reference: 91 | company_id: integer 92 | transaction_id: integer 93 | coupon_id: string 94 | operation_type: string 95 | payment_type: string 96 | available_actions: array 97 | installment_amount: number 98 | deferred_period: string 99 | date_approved: datetime 100 | authorization_code: string 101 | transaction_order_id: string 102 | feedback: array 103 | shipping: 104 | cost: integer 105 | currency_id: string 106 | date_created: string 107 | date_first_printed: string 108 | id: integer 109 | picking_type: string 110 | receiver_address: 111 | address_line: string 112 | city: 113 | id: integer 114 | name: string 115 | comment: string 116 | country: 117 | id: integer 118 | name: string 119 | id: integer 120 | latitude: string 121 | longitude: string 122 | state: 123 | id: integer 124 | name: string 125 | street_name: string 126 | street_number: string 127 | zip_code: string 128 | sender_id: integer 129 | service_id: integer 130 | shippingCode: string 131 | shipment_type: string 132 | shipping_items: 133 | - 134 | description: string 135 | dimensions: string 136 | id: string 137 | quantity: integer 138 | shipping_mode: string 139 | shipping_option: 140 | cost: number 141 | currency_id: string 142 | estimated_delivery: 143 | date: string 144 | time_from: string 145 | time_to: string 146 | id: integer 147 | name: string 148 | shipping_method_id: integer 149 | speed: 150 | handling: string 151 | shipping: string 152 | status: string 153 | substatus: string 154 | tags: array 155 | -------------------------------------------------------------------------------- /tests/Entity/Order/Payments/AtmTransferReferenceTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Payments; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Payments\AtmTransferReference; 15 | use PHPUnit\Framework\TestCase as CoreTestCase; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Payments\AtmTransferReference 19 | * 20 | * @method int getCompanyId() A $company_id acessor. 21 | * @method setCompanyId(integer $company_id) A $company_id setter 22 | * @method int getTransactionId() A $transaction_id acessor. 23 | * @method setTransactionId(integer $transaction_id) A $transaction_id setter 24 | */ 25 | class AtmTransferReferenceTest extends CoreTestCase 26 | { 27 | use EntityTrait; 28 | 29 | const QUALIFIED = AtmTransferReference::class; 30 | 31 | public static function setUpBeforeClass(): void 32 | { 33 | static::setFullyQualifiedObject(self::QUALIFIED); 34 | parent::setUpBeforeClass(); 35 | } 36 | 37 | /** 38 | * @return AtmTransferReference 39 | */ 40 | public function dataProviderAtmTransferReference() 41 | { 42 | $expected = [ 43 | 'company_id' => 'integer', 44 | 'transaction_id' => 'integer', 45 | ]; 46 | 47 | return $this->dataProviderEntitySchema(self::QUALIFIED, $expected); 48 | } 49 | 50 | /** 51 | * @testdox Have a getter ``getCompanyId()`` to get ``CompanyId`` 52 | * @dataProvider dataProviderAtmTransferReference 53 | * @cover ::getCompanyId 54 | * @small 55 | * 56 | * @param AtmTransferReference $atmTransferReference Main Object 57 | * @param array $expected Fixture data 58 | */ 59 | public function testGetCompanyId(AtmTransferReference $atmTransferReference, array $expected) 60 | { 61 | $atmTransferReference->setCompanyId($expected['company_id']); 62 | $this->assertSame($expected['company_id'], $atmTransferReference->getCompanyId()); 63 | } 64 | 65 | /** 66 | * @testdox Have a setter ``setCompanyId()`` to set ``CompanyId`` 67 | * @dataProvider dataProviderAtmTransferReference 68 | * @cover ::setCompanyId 69 | * @small 70 | * 71 | * @param AtmTransferReference $atmTransferReference Main Object 72 | * @param array $expected Fixture data 73 | */ 74 | public function testSetCompanyId(AtmTransferReference $atmTransferReference, array $expected) 75 | { 76 | $atmTransferReference->setCompanyId($expected['company_id']); 77 | $this->assertSame($expected['company_id'], $atmTransferReference->getCompanyId()); 78 | } 79 | 80 | /** 81 | * @testdox Have a getter ``getTransactionId()`` to get ``TransactionId`` 82 | * @dataProvider dataProviderAtmTransferReference 83 | * @cover ::getTransactionId 84 | * @small 85 | * 86 | * @param AtmTransferReference $atmTransferReference Main Object 87 | * @param array $expected Fixture data 88 | */ 89 | public function testGetTransactionId(AtmTransferReference $atmTransferReference, array $expected) 90 | { 91 | $atmTransferReference->setTransactionId($expected['transaction_id']); 92 | $this->assertSame($expected['transaction_id'], $atmTransferReference->getTransactionId()); 93 | } 94 | 95 | /** 96 | * @testdox Have a setter ``setTransactionId()`` to set ``TransactionId`` 97 | * @dataProvider dataProviderAtmTransferReference 98 | * @cover ::setTransactionId 99 | * @small 100 | * 101 | * @param AtmTransferReference $atmTransferReference Main Object 102 | * @param array $expected Fixture data 103 | */ 104 | public function testSetTransactionId(AtmTransferReference $atmTransferReference, array $expected) 105 | { 106 | $atmTransferReference->setTransactionId($expected['transaction_id']); 107 | $this->assertSame($expected['transaction_id'], $atmTransferReference->getTransactionId()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Resources/mockup/Product/MLB803848501.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "MLB803848501", 3 | "site_id": "MLB", 4 | "title": "Perfume Azzaro Pour Homme Edt Masculino", 5 | "subtitle": null, 6 | "seller_id": 231401236, 7 | "category_id": "MLB5399", 8 | "official_store_id": null, 9 | "price": 369.55, 10 | "base_price": 369.55, 11 | "original_price": null, 12 | "currency_id": "BRL", 13 | "initial_quantity": 181, 14 | "available_quantity": 181, 15 | "sold_quantity": 0, 16 | "buying_mode": "buy_it_now", 17 | "listing_type_id": "gold_special", 18 | "start_time": "2016-10-14T20:04:11.000Z", 19 | "stop_time": "2016-10-16T10:09:05.000Z", 20 | "condition": "new", 21 | "permalink": "http://produto.mercadolivre.com.br/MLB-803848501-perfume-azzaro-pour-homme-edt-masculino-_JM", 22 | "thumbnail": "http://mlb-s1-p.mlstatic.com/900015-MLB25103831394_102016-I.jpg", 23 | "secure_thumbnail": "https://mlb-s1-p.mlstatic.com/900015-MLB25103831394_102016-I.jpg", 24 | "pictures": [ 25 | { 26 | "id": "900015-MLB25103831394_102016", 27 | "url": "http://mlb-s1-p.mlstatic.com/900015-MLB25103831394_102016-O.jpg", 28 | "secure_url": "https://mlb-s1-p.mlstatic.com/900015-MLB25103831394_102016-O.jpg", 29 | "size": "400x400", 30 | "max_size": "400x400", 31 | "quality": "" 32 | } 33 | ], 34 | "video_id": "dQw4w9WgXcQ", 35 | "description": [ 36 | { 37 | "id": "MLB803848501-1846315479" 38 | } 39 | ], 40 | "accepts_mercadopago": true, 41 | "non_mercado_pago_payment_methods": [], 42 | "shipping": { 43 | "mode": "not_specified", 44 | "local_pick_up": false, 45 | "free_shipping": false, 46 | "methods": [], 47 | "dimensions": null, 48 | "tags": [] 49 | }, 50 | "international_delivery_mode": "none", 51 | "seller_address": { 52 | "id": 195382919, 53 | "comment": "", 54 | "address_line": "", 55 | "zip_code": "", 56 | "city": { 57 | "id": "TUxCQ0JBUmQ0MjRj", 58 | "name": "Barreiras" 59 | }, 60 | "state": { 61 | "id": "BR-BA", 62 | "name": "Bahia" 63 | }, 64 | "country": { 65 | "id": "BR", 66 | "name": "Brasil" 67 | }, 68 | "latitude": -12.14578697, 69 | "longitude": -44.99915513, 70 | "search_location": { 71 | "neighborhood": { 72 | "id": "", 73 | "name": "" 74 | }, 75 | "city": { 76 | "id": "TUxCQ0JBUmQ0MjRj", 77 | "name": "Barreiras" 78 | }, 79 | "state": { 80 | "id": "TUxCUEJBSEFlYmEx", 81 | "name": "Bahia" 82 | } 83 | } 84 | }, 85 | "seller_contact": null, 86 | "location": {}, 87 | "geolocation": { 88 | "latitude": -12.14349776, 89 | "longitude": -44.99464125 90 | }, 91 | "coverage_areas": [], 92 | "attributes": [ 93 | { 94 | "id": "BRAND", 95 | "name": "Marca", 96 | "value_id": "23019", 97 | "value_name": "Azzaro", 98 | "attribute_group_id": "DFLT", 99 | "attribute_group_name": "Outros" 100 | }, 101 | { 102 | "id": "GENDER", 103 | "name": "Gênero", 104 | "value_id": "111070", 105 | "value_name": "Masculino", 106 | "attribute_group_id": "DFLT", 107 | "attribute_group_name": "Outros" 108 | } 109 | ], 110 | "warnings": [], 111 | "listing_source": "", 112 | "variations": [ 113 | { 114 | "id": 13065333854, 115 | "attribute_combinations": [ 116 | { 117 | "id": null, 118 | "name": "Tamanho", 119 | "value_id": null, 120 | "value_name": "30 ml" 121 | } 122 | ], 123 | "price": 139, 124 | "available_quantity": 168, 125 | "sold_quantity": 0, 126 | "picture_ids": [], 127 | "seller_custom_field": null, 128 | "catalog_product_id": null 129 | }, 130 | { 131 | "id": 13064397485, 132 | "attribute_combinations": [ 133 | { 134 | "id": null, 135 | "name": "Tamanho", 136 | "value_id": null, 137 | "value_name": "100 ml" 138 | } 139 | ], 140 | "price": 369.55, 141 | "available_quantity": 13, 142 | "sold_quantity": 0, 143 | "picture_ids": [ 144 | "900015-MLB25103831394_102016" 145 | ], 146 | "seller_custom_field": null, 147 | "catalog_product_id": null 148 | } 149 | ], 150 | "status": "closed", 151 | "sub_status": [], 152 | "tags": [ 153 | "immediate_payment" 154 | ], 155 | "warranty": null, 156 | "catalog_product_id": null, 157 | "domain_id": null, 158 | "parent_item_id": null, 159 | "differential_pricing": null, 160 | "deal_ids": [], 161 | "automatic_relist": false, 162 | "date_created": "2016-10-14T20:04:11.000Z", 163 | "last_updated": "2016-10-16T10:09:30.000Z" 164 | } 165 | -------------------------------------------------------------------------------- /tests/Entity/Message/ManagerTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Message; 12 | 13 | use Gpupo\MercadolivreSdk\Client\Client; 14 | use Gpupo\MercadolivreSdk\Entity\Message\From; 15 | use Gpupo\MercadolivreSdk\Entity\Message\Manager; 16 | use Gpupo\MercadolivreSdk\Entity\Message\Message; 17 | use Gpupo\MercadolivreSdk\Entity\Message\MessageCollection; 18 | use Gpupo\MercadolivreSdk\Entity\Message\Text; 19 | use Gpupo\MercadolivreSdk\Entity\Message\To; 20 | use Gpupo\MercadolivreSdk\Entity\Message\User; 21 | use Gpupo\MercadolivreSdk\Entity\Message\UserCollection; 22 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 23 | 24 | /** 25 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Message\Manager 26 | */ 27 | class ManagerTest extends TestCaseAbstract 28 | { 29 | /** 30 | * @testdox Administra operações 31 | */ 32 | public function testManager() 33 | { 34 | $manager = $this->getManager('list.json'); 35 | 36 | $this->assertInstanceOf(Manager::class, $manager); 37 | 38 | return $manager; 39 | } 40 | 41 | public function testCreateMessage() 42 | { 43 | $sdk = $this->getFactory(); 44 | $message = $sdk->createMessage([ 45 | 'from' => [ 46 | 'user_id' => '2', 47 | ], 48 | 'to' => [ 49 | [ 50 | 'user_id' => '1', 51 | 'site_id' => 'MLB', 52 | 'resource' => 'foo', 53 | 'resource_id' => 'xxx', 54 | ], 55 | ], 56 | 'subject' => 'Foobar', 57 | 'text' => ['plain' => 'Hello World'], 58 | ]); 59 | 60 | $manager = $this->getManager('creationResponse.json'); 61 | $returnedMessage = $manager->create($message); 62 | $this->assertSame('2016-09-01T05:15:25.821Z', $returnedMessage->getDateReceived()); 63 | $this->assertEmpty($returnedMessage->getDateRead()); 64 | } 65 | 66 | /** 67 | * @depends testManager 68 | * @covers ::getClient 69 | * 70 | * @param mixed $manager 71 | */ 72 | public function testPossuiObjetoClient($manager) 73 | { 74 | $this->assertInstanceOf(Client::class, $manager->getClient()); 75 | } 76 | 77 | /** 78 | * @testdox Get messages based on order number 79 | * @covers ::findByOrderId 80 | * @covers ::execute 81 | */ 82 | public function testFindByOrderId() 83 | { 84 | $manager = $this->getManager('list.json'); 85 | $order = $this->getFactory()->createOrder(['id' => 1068825849]); 86 | $messages = $manager->findByOrderId($order); 87 | $message = $messages->first(); 88 | $this->assertInstanceOf(MessageCollection::class, $messages); 89 | $this->assertInstanceOf(Message::class, $message); 90 | $this->assertInstanceOf(From::class, $message->getFrom()); 91 | $this->assertInstanceOf(User::class, $message->getFrom()); 92 | $this->assertInstanceOf(To::class, $message->getTo()); 93 | $this->assertInstanceOf(UserCollection::class, $message->getTo()); 94 | $this->assertInstanceOf(User::class, $message->getTo()->first()); 95 | $this->assertInstanceOf(Text::class, $message->getText()); 96 | $this->commonAssertsMessage($messages); 97 | } 98 | 99 | public function commonAssertsMessage(MessageCollection $messages) 100 | { 101 | $this->assertSame('43b450d6bd3f47fb94394041b26c519f', $messages->first()->getMessageId()); 102 | $this->assertSame((int) '76601286', (int) $messages->first()->getFrom()->getUserId()); 103 | $this->assertSame((int) '106459677', (int) $messages->first()->getTo()->first()->getUserId()); 104 | } 105 | 106 | /** 107 | * @depends testManager 108 | * 109 | * @param mixed $manager 110 | */ 111 | public function testIsHttpStatusCodeOK($manager) 112 | { 113 | $this->assertTrue($manager->isHttpStatusCodeOK(200)); 114 | $this->assertTrue($manager->isHttpStatusCodeOK(299)); 115 | $this->assertFalse($manager->isHttpStatusCodeOK(199)); 116 | $this->assertFalse($manager->isHttpStatusCodeOK(300)); 117 | $this->assertFalse($manager->isHttpStatusCodeOK(502)); 118 | } 119 | 120 | protected function getManager($filename = 'item.json') 121 | { 122 | $manager = $this->getFactory()->factoryManager('message'); 123 | $manager->setDryRun($this->factoryResponseFromFixture('mockup/Message/'.$filename)); 124 | 125 | return $manager; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /tests/Entity/Product/TranslatorTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Product; 12 | 13 | use Gpupo\CommonSchema\TranslatorDataCollection; 14 | use Gpupo\MercadolivreSdk\Entity\Product\Product; 15 | use Gpupo\MercadolivreSdk\Entity\Product\Translator; 16 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 17 | 18 | /** 19 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Product\Translator 20 | */ 21 | class TranslatorTest extends TestCaseAbstract 22 | { 23 | /** 24 | * @return \Gpupo\MercadolivreSdk\Entity\Product\Translator 25 | */ 26 | public function dataProviderTranslator() 27 | { 28 | $list = []; 29 | 30 | foreach ($this->providerProducts() as $product) { 31 | if (!is_a($product, Product::class)) { 32 | throw new \InvalidArgumentException(sprintf('$product must be a mercadolivre-sdk entity! [%s] received', \get_class($product))); 33 | } 34 | $translator = new Translator(['native' => $product]); 35 | 36 | $list[] = [$translator]; 37 | } 38 | 39 | return $list; 40 | } 41 | 42 | /** 43 | * @testdox Falha ao tentar traduzir para extrangeiro sem possuir nativo 44 | * @covers ::translateFrom 45 | */ 46 | public function testLoadMapFailForeign() 47 | { 48 | $this->expectException(\Gpupo\CommonSchema\TranslatorException::class); 49 | $this->expectExceptionMessage('Foreign object missed!'); 50 | 51 | $t = new Translator(); 52 | $t->import(); 53 | } 54 | 55 | /** 56 | * @testdox Falha ao tentar traduzir para nativo sem possuir estrangeiro 57 | * @covers ::translateTo 58 | */ 59 | public function testLoadMapFailNative() 60 | { 61 | $this->expectException(\Gpupo\CommonSchema\TranslatorException::class); 62 | $this->expectExceptionMessage('Product missed!'); 63 | 64 | $t = new Translator(); 65 | $t->export(); 66 | } 67 | 68 | /** 69 | * @testdox ``loadMap()`` 70 | * @cover ::loadMap 71 | * 72 | * @dataProvider dataProviderArrayExpected 73 | * @group todo 74 | * 75 | * @param mixed $expected 76 | */ 77 | public function testLoadMap($expected) 78 | { 79 | $product = new Product($expected); 80 | 81 | $t = $this->proxy(new Translator()); 82 | $foreign = new TranslatorDataCollection([ 83 | 'skuSellerId' => '111', 84 | ]); 85 | 86 | $t->setForeign($foreign); 87 | $t->setNative($product); 88 | 89 | $list = $t->loadMap('native'); 90 | $this->assertSame($product->get('skuSellerId'), $list['productId']); 91 | 92 | $list = $t->loadMap('foreign'); 93 | $this->assertSame($foreign->get('productId'), $list['skuSellerId']); 94 | } 95 | 96 | /** 97 | * @testdox ``export()`` 98 | * @cover ::translateTo 99 | * @group todo 100 | * @dataProvider dataProviderTranslator 101 | */ 102 | public function testTranslateTo(Translator $translator) 103 | { 104 | $translated = $translator->export(); 105 | $this->assertInstanceOf(TranslatorDataCollection::class, $translated); 106 | $this->assertIsArray($translated->toArray(), 'internal type'); 107 | } 108 | 109 | /** 110 | * @testdox ``import()`` 111 | * @cover ::translateFrom 112 | * @group todo 113 | * @dataProvider dataProviderTranslator 114 | */ 115 | public function testTranslateFrom(Translator $translator) 116 | { 117 | $foreign = $translator->export(); 118 | $this->assertInstanceOf(TranslatorDataCollection::class, $foreign); 119 | $translator->setForeign($foreign); 120 | $translated = $translator->import(); 121 | $this->assertInstanceOf(Product::class, $translated); 122 | $this->assertIsArray($translated->toArray(), 'internal type'); 123 | } 124 | 125 | public function dataProviderArrayExpected() 126 | { 127 | $list = []; 128 | $i = 1; 129 | while ($i <= 50) { 130 | ++$i; 131 | $id = rand(); 132 | $price = rand(100, 9999) / rand(3, 55); 133 | $list[] = [[ 134 | 'skuSellerId' => $id, 135 | 'price' => [ 136 | 'default' => (float) $price, 137 | 'offer' => (float) ($price * rand(40, 97)) / 100, 138 | ], 139 | 'stock' => rand(), 140 | 'status' => ($price > rand()), 141 | 'brand' => 'Acme', 142 | ]]; 143 | } 144 | 145 | return $list; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /tests/Entity/Order/Shipping/EstimatedDeliveryTest.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Shipping; 12 | 13 | use Gpupo\CommonSdk\Tests\Traits\EntityTrait; 14 | use Gpupo\MercadolivreSdk\Entity\Order\Shipping\EstimatedDelivery; 15 | use PHPUnit\Framework\TestCase as CoreTestCase; 16 | 17 | /** 18 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Shipping\EstimatedDelivery 19 | * 20 | * @method string getDate() A $date acessor. 21 | * @method setDate(string $date) A $date setter 22 | * @method string getTimeFrom() A $time_from acessor. 23 | * @method setTimeFrom(string $time_from) A $time_from setter 24 | * @method string getTimeTo() A $time_to acessor. 25 | * @method setTimeTo(string $time_to) A $time_to setter 26 | */ 27 | class EstimatedDeliveryTest extends CoreTestCase 28 | { 29 | use EntityTrait; 30 | 31 | const QUALIFIED = EstimatedDelivery::class; 32 | 33 | public static function setUpBeforeClass(): void 34 | { 35 | static::setFullyQualifiedObject(self::QUALIFIED); 36 | parent::setUpBeforeClass(); 37 | } 38 | 39 | /** 40 | * @return EstimatedDelivery 41 | */ 42 | public function dataProviderEstimatedDelivery() 43 | { 44 | $expected = [ 45 | 'date' => 'string', 46 | 'time_from' => 'string', 47 | 'time_to' => 'string', 48 | ]; 49 | 50 | return $this->dataProviderEntitySchema(self::QUALIFIED, $expected); 51 | } 52 | 53 | /** 54 | * @testdox Have a getter ``getDate()`` to get ``Date`` 55 | * @dataProvider dataProviderEstimatedDelivery 56 | * @cover ::getDate 57 | * @small 58 | * 59 | * @param EstimatedDelivery $estimatedDelivery Main Object 60 | * @param array $expected Fixture data 61 | */ 62 | public function testGetDate(EstimatedDelivery $estimatedDelivery, array $expected) 63 | { 64 | $estimatedDelivery->setDate($expected['date']); 65 | $this->assertSame($expected['date'], $estimatedDelivery->getDate()); 66 | } 67 | 68 | /** 69 | * @testdox Have a setter ``setDate()`` to set ``Date`` 70 | * @dataProvider dataProviderEstimatedDelivery 71 | * @cover ::setDate 72 | * @small 73 | * 74 | * @param EstimatedDelivery $estimatedDelivery Main Object 75 | * @param array $expected Fixture data 76 | */ 77 | public function testSetDate(EstimatedDelivery $estimatedDelivery, array $expected) 78 | { 79 | $estimatedDelivery->setDate($expected['date']); 80 | $this->assertSame($expected['date'], $estimatedDelivery->getDate()); 81 | } 82 | 83 | /** 84 | * @testdox Have a getter ``getTimeFrom()`` to get ``TimeFrom`` 85 | * @dataProvider dataProviderEstimatedDelivery 86 | * @cover ::getTimeFrom 87 | * @small 88 | * 89 | * @param EstimatedDelivery $estimatedDelivery Main Object 90 | * @param array $expected Fixture data 91 | */ 92 | public function testGetTimeFrom(EstimatedDelivery $estimatedDelivery, array $expected) 93 | { 94 | $estimatedDelivery->setTimeFrom($expected['time_from']); 95 | $this->assertSame($expected['time_from'], $estimatedDelivery->getTimeFrom()); 96 | } 97 | 98 | /** 99 | * @testdox Have a setter ``setTimeFrom()`` to set ``TimeFrom`` 100 | * @dataProvider dataProviderEstimatedDelivery 101 | * @cover ::setTimeFrom 102 | * @small 103 | * 104 | * @param EstimatedDelivery $estimatedDelivery Main Object 105 | * @param array $expected Fixture data 106 | */ 107 | public function testSetTimeFrom(EstimatedDelivery $estimatedDelivery, array $expected) 108 | { 109 | $estimatedDelivery->setTimeFrom($expected['time_from']); 110 | $this->assertSame($expected['time_from'], $estimatedDelivery->getTimeFrom()); 111 | } 112 | 113 | /** 114 | * @testdox Have a getter ``getTimeTo()`` to get ``TimeTo`` 115 | * @dataProvider dataProviderEstimatedDelivery 116 | * @cover ::getTimeTo 117 | * @small 118 | * 119 | * @param EstimatedDelivery $estimatedDelivery Main Object 120 | * @param array $expected Fixture data 121 | */ 122 | public function testGetTimeTo(EstimatedDelivery $estimatedDelivery, array $expected) 123 | { 124 | $estimatedDelivery->setTimeTo($expected['time_to']); 125 | $this->assertSame($expected['time_to'], $estimatedDelivery->getTimeTo()); 126 | } 127 | 128 | /** 129 | * @testdox Have a setter ``setTimeTo()`` to set ``TimeTo`` 130 | * @dataProvider dataProviderEstimatedDelivery 131 | * @cover ::setTimeTo 132 | * @small 133 | * 134 | * @param EstimatedDelivery $estimatedDelivery Main Object 135 | * @param array $expected Fixture data 136 | */ 137 | public function testSetTimeTo(EstimatedDelivery $estimatedDelivery, array $expected) 138 | { 139 | $estimatedDelivery->setTimeTo($expected['time_to']); 140 | $this->assertSame($expected['time_to'], $estimatedDelivery->getTimeTo()); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /tests/Entity/Order/Decorator/AbstractDecoratorTestCase.php: -------------------------------------------------------------------------------- 1 | 7 | * For the information of copyright and license you should read the file LICENSE which is 8 | * distributed with this source code. For more information, see 9 | */ 10 | 11 | namespace Gpupo\MercadolivreSdk\Tests\Entity\Order\Decorator; 12 | 13 | use Gpupo\MercadolivreSdk\Entity\Order\Order; 14 | use Gpupo\MercadolivreSdk\Tests\TestCaseAbstract; 15 | 16 | /** 17 | * @coversDefaultClass \Gpupo\MercadolivreSdk\Entity\Order\Decorator\AbstractDecorator 18 | */ 19 | abstract class AbstractDecoratorTestCase extends TestCaseAbstract 20 | { 21 | /** 22 | * @testdox Recebe o objeto ``Order`` 23 | * 24 | * @dataProvider dataProviderOrders 25 | * @covers ::setOrder 26 | */ 27 | public function testSetOrder(Order $order) 28 | { 29 | $this->assertInstanceOf(Order::class, $this->factory() 30 | ->setOrder($order)->getOrder()); 31 | } 32 | 33 | /** 34 | * @testdox Falha ao validar ``Order`` com informações mínimas requeridas ausentes 35 | * 36 | * @covers ::factoryArray 37 | */ 38 | public function testValidateFail() 39 | { 40 | $this->expectException(\Exception::class); 41 | $decorator = $this->getDecorator(); 42 | $decorator->validate(); 43 | } 44 | 45 | /** 46 | * @testdox Falha ao tentar submeter uma ordem incompleta para mudança de status 47 | * @covers ::factoryArray 48 | * @covers ::toArray 49 | */ 50 | public function testToArrayFail() 51 | { 52 | $this->expectException(\Exception::class); 53 | $this->expectExceptionMessage('Attribute invalid: Order'); 54 | $o = $this->proxy($this->getDecorator()); 55 | $o->set('order', ''); 56 | $o->toArray(); 57 | } 58 | 59 | /** 60 | * @testdox Tem sucesso ao validar as informações mínimas requeridas para uma mudança de status 61 | * 62 | * @covers \Gpupo\MercadolivreSdk\Entity\Order\Decorator\AbstractDecorator::validate 63 | * @covers ::validate 64 | * @covers ::toArray 65 | * @dataProvider dataProviderOrders 66 | */ 67 | public function testValidate(Order $order) 68 | { 69 | $this->output(sprintf('Target %s ', $this->target)); 70 | $decorator = $this->getDecorator($this->getExpectedArray())->setOrder($order); 71 | $decorator->validate(); 72 | $this->assertInstanceOf(Order::class, $decorator->getOrder()); 73 | } 74 | 75 | /** 76 | * @testdox Prepara as informações como de acordo com o pedido na mudança de status 77 | * 78 | * @dataProvider dataProviderOrders 79 | * @covers \Gpupo\MercadolivreSdk\Entity\Order\Decorator\AbstractDecorator 80 | * @covers ::toArray 81 | * @covers ::factoryArray 82 | */ 83 | public function testToArray(Order $order) 84 | { 85 | $this->output(sprintf('Target %s ', $this->target)); 86 | $decorator = $this->factoryDecorator($order, $this->getExpectedArray()); 87 | $this->assertSame($this->getExpectedArray(), $decorator->toArray()); 88 | } 89 | 90 | /** 91 | * @testdox Prepara JSON de acordo com o pedido na mudança de status 92 | * 93 | * @covers ::toArray 94 | * @covers ::toJson 95 | * @covers ::factoryArray 96 | * @dataProvider dataProviderOrders 97 | */ 98 | public function testToJson(Order $order) 99 | { 100 | $this->output(sprintf('Target %s ', $this->target)); 101 | $decorator = $this->factoryDecorator($order, $this->getExpectedArray()); 102 | $this->assertSame($this->getExpectedJson(), $decorator->toJson()); 103 | } 104 | 105 | /** 106 | * @testdox Lida com as mensagens de validação 107 | * @covers ::fail 108 | */ 109 | public function testFailMessage() 110 | { 111 | $this->output(sprintf('Target %s ', $this->target)); 112 | $this->expectException(\InvalidArgumentException::class); 113 | $o = $this->proxy($this->getDecorator()); 114 | $o->fail(); 115 | } 116 | 117 | /** 118 | * @testdox Lida com as mensagens de validação especificando o atributo com problemas 119 | * @covers ::invalid 120 | */ 121 | public function testInvalidMessage() 122 | { 123 | $this->output(sprintf('Target %s ', $this->target)); 124 | $this->expectException(\InvalidArgumentException::class); 125 | $this->expectExceptionMessage('Attribute invalid: foo'); 126 | $o = $this->proxy($this->getDecorator()); 127 | $o->invalid('foo'); 128 | } 129 | 130 | /** 131 | * @testdox Possui validação de Order 132 | * @covers ::validate 133 | */ 134 | public function testBasicValidate() 135 | { 136 | $this->output(sprintf('Target %s ', $this->target)); 137 | $this->expectException(\InvalidArgumentException::class); 138 | $this->expectExceptionMessage('Attribute invalid: Order'); 139 | $o = $this->proxy($this->getDecorator()); 140 | $o->set('order', ''); 141 | $o->validate(); 142 | } 143 | 144 | protected function getExpectedArray() 145 | { 146 | return $this->getResourceJson('mockup/Order/Status/'.$this->target.'.json'); 147 | } 148 | 149 | protected function getExpectedJson() 150 | { 151 | return trim($this->getResourceContent('mockup/Order/Status/'.$this->target.'.json')); 152 | } 153 | 154 | protected function getDecorator($data = []) 155 | { 156 | return $this->factory($data)->setLogger($this->getLogger()); 157 | } 158 | 159 | protected function factoryDecorator(Order $order, $data = []) 160 | { 161 | $decorator = $this->getDecorator($data); 162 | $decorator->setOriginalOrder($order); 163 | 164 | return $decorator->setOrder($order); 165 | } 166 | } 167 | --------------------------------------------------------------------------------