Skip to content

davisngl/printful-shopify

Repository files navigation

Printful Shopify app

Application used for pulling products in an async fashion from Shopify API, along with their storage and visual display on the web UI.

Pre-requisites

Project runs on minimal required PHP version 8.2.
It requires: ext-pdo, ext-pdo_mysql and ext-intl extensions to be installed.
If they are not in the system, install by running sudo apt install php8.2-{pdo,mysql,intl}.

Also, a redis-server and mysql 8 by default should be installed and running on system (didn't have time to dockerize).

If you are going to use other RDBMS, you should install the appropriate PHP extensions for PDO (e.g., ext-pdo_pgsql and what not).

Installation

  1. Clone the repository
  2. Run cp .env.example .env to copy environment variables onto .env file which will be used in the app
  3. Run composer install to install all the back-end dependencies. There are no front-end dependencies to install.
  4. Run mysql -u <database_user> -p < src/Database/init.sql from project root to migrate database schema. Be sure to use your local DB credentials
  5. Fill out missing environment variable values (to get Shopify access token, custom development store URI and store API version, visit development stores and custom apps in Shopify docs). When creating a custom app, it will automatically seed with products, they'll do fine for our purposes.

Easiest way to start, would be to run php -S 127.0.0.1:8888 -t src/public in root directory and visit 127.0.0.1:8888 in your browser.
Choose the appropriate port if port 8888 is already listening.

Background job processing

For processing potentially long-running tasks, a queue worker is being used. By default, it uses Redis for storage through predis/predis Composer package. To start it, run php start-queue-worker.php and leave it running.
When there will be a task to process and when it's done, queue worker will let you know in the console where you started the process.

NB: For the sake of this task, this is mandatory in order for products to be refreshed. Otherwise, you can just instantiate RefreshProducts job and run handle method to process it synchronously.

Routing & controllers

For simplicity, routes and "controllers" are handled in one file - Routing/routes.php, controllers are Closures with ContainerInterface injected into them that you can use.
In case of needing a new route, register it with $router-><method>('/test', fn () => ...). When route is not found, closure defined with $router->abortWith(fn () => ...) will be called.

Extending the functionality

Currently, for sake of showcasing, database, views, http requests, queue worker and queue driver are registered in service container.

For example, to create different storage logic for products, you can create an implementation to Database/Contracts/BaseDatabase interface.
These implementations can be then added in DatabaseDriverFactory as on of the options it could resolve to. Same with QueueDriverFactory. It would be better to allow extensibility through some addFactoryDefinition closure that would add to resolvable drivers, but for now, you have to manually register new drivers.

Afterthought

This app is not production ready. For it to be ready, there should be a lot more try/catch statements in place to handle mishaps, edge-cases should be covered when it comes to unexpected results from DB/elsewhere and above all - a lot more tests to cover functionality and its edge-cases etc.
In order to do all of that, it would take well over the time it already took, therefore I have tried to prioritize certain things.

This should be used as a display of my skill set only.

About

Test task for Printful Shopify task

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published