142 lines
5.6 KiB
Markdown
142 lines
5.6 KiB
Markdown
# Technology Stack & Integrations
|
||
|
||
## Languages
|
||
|
||
| Language | Version | Notes |
|
||
|----------|---------|-------|
|
||
| PHP | 7.4 – <8.0 | Production constraint — no PHP 8.0+ syntax |
|
||
| JavaScript | ES5 + jQuery 2.1.3 | No modern framework |
|
||
| CSS | Bootstrap 4.x (pre-compiled SCSS) | No build pipeline |
|
||
|
||
**PHP 8.0+ features explicitly forbidden:**
|
||
- `match` expressions → use ternary / if-else
|
||
- Named arguments
|
||
- Union types (`int|string`) → use single type + docblock
|
||
- `str_contains()`, `str_starts_with()`, `str_ends_with()` → use `strpos()`
|
||
|
||
## Core Libraries
|
||
|
||
| Library | Version | Location | Purpose |
|
||
|---------|---------|----------|---------|
|
||
| Medoo | 1.7.10 | `libraries/medoo/medoo.php` | Database ORM |
|
||
| PHPMailer | classic | `libraries/phpmailer/` | Email sending |
|
||
| RedBeanPHP | — | `libraries/rb.php` | Legacy ORM — **unused, candidate for removal** |
|
||
|
||
## Frontend Libraries
|
||
|
||
| Library | Location | Purpose |
|
||
|---------|----------|---------|
|
||
| jQuery | 2.1.3 | DOM / AJAX |
|
||
| jQuery Migrate | 1.0.0 | Backward compat |
|
||
| Bootstrap | 4.1.3 / 4.5.2 | `libraries/bootstrap*/` |
|
||
| CKEditor | 4.x | `libraries/ckeditor/` | Rich text editor |
|
||
| ApexCharts | — | `libraries/apexcharts/` | Admin charts |
|
||
| FancyBox | 2 + 3 | `libraries/fancyBox/`, `fancybox3/` | Lightbox |
|
||
| Plupload | — | `libraries/plupload/` | File uploads |
|
||
| Selectize.js | — | — | Select dropdowns |
|
||
| Lozad.js | — | — | Lazy loading |
|
||
| Swiper | — | — | Carousel/slider |
|
||
| CodeMirror | — | `libraries/codemirror/` | Code editor |
|
||
| Font Awesome | 5.7.0 | `libraries/fontawesome-5.7.0/` | Icons |
|
||
| File Manager | 9.14.1 & 9.14.2 | `libraries/filemanager-9.14.*/` | File browsing |
|
||
|
||
## Database
|
||
|
||
- **ORM**: Medoo 1.7.10 (custom-extended with Redis support)
|
||
- **Engine**: MySQL
|
||
- **Table prefix**: `pp_`
|
||
- **Connection**: `new medoo([...])` in each entry point via credentials from `config.php`
|
||
- **Key tables**: `pp_shop_products`, `pp_shop_orders`, `pp_shop_categories`, `pp_shop_clients`
|
||
|
||
## Caching
|
||
|
||
- **Technology**: Redis
|
||
- **PHP extension**: Native `Redis` class
|
||
- **Wrapper**: `\Shared\Cache\CacheHandler` (singleton via `RedisConnection`)
|
||
- **Config**: `config.php` → `$config['redis']['host/port/password']`
|
||
- **Serialization**: PHP `serialize()` / `unserialize()`
|
||
- **Default TTL**: 86400 seconds (24h)
|
||
- **Key patterns**:
|
||
- `shop\product:{id}:{lang_id}:{hash}` — product details
|
||
- `ProductRepository::getProductPermutationQuantityOptions:v2:{id}:*`
|
||
- `pp_routes:all` — URL routing patterns
|
||
- `pp_settings_cache` — shop settings
|
||
|
||
## Email
|
||
|
||
- **Library**: PHPMailer (classic, not v6)
|
||
- **Config**: `config.php` (host, port, login, password)
|
||
- **Helpers**:
|
||
- `\Shared\Helpers\Helpers::send_email($to, $subject, $text, $reply, $file)`
|
||
- `\Shared\Email\Email::send(...)` — newsletter / template-based
|
||
- **Issue**: Duplicate PHPMailer logic in both classes — should be unified
|
||
|
||
## HTTP Client
|
||
|
||
- **Technology**: Native PHP cURL (`curl_init`, `curl_setopt`, `curl_exec`)
|
||
- **No abstraction library** (no Guzzle, Symfony HTTP Client)
|
||
- **Used in**: `IntegrationsRepository.php` (Apilo calls), `cron.php` (image downloads)
|
||
|
||
## Dev & Build Tools
|
||
|
||
| Tool | Purpose |
|
||
|------|---------|
|
||
| Composer | PHP dependency management |
|
||
| PHPUnit 9.6 | Testing (`phpunit.phar`) |
|
||
| PowerShell `test.ps1` | Recommended test runner |
|
||
| No webpack/Vite/Gulp | SCSS pre-compiled, assets served as-is |
|
||
|
||
## External Integrations
|
||
|
||
### Apilo (ERP/WMS)
|
||
- **Auth**: OAuth 2.0 Bearer token (client_id + client_secret from `pp_shop_apilo_settings`)
|
||
- **Base URL**: `https://projectpro.apilo.com/rest/api/`
|
||
- **Sync operations**: order sending, payment sync, status polling, product qty/price sync, pricelist sync
|
||
- **Code**: `autoload/Domain/Integrations/IntegrationsRepository.php`
|
||
- **Cron jobs**: `APILO_SEND_ORDER`, `APILO_SYNC_PAYMENT`, `APILO_STATUS_POLL`, `APILO_PRODUCT_SYNC`, `APILO_PRICELIST_SYNC`
|
||
- **Logging**: `\Domain\Integrations\ApiloLogger` → `pp_log` table
|
||
|
||
### Ekomi (Reviews)
|
||
- **Type**: CSV export
|
||
- **Code**: `api.php` → generates `/ekomi/ekomi-{date}.csv`
|
||
|
||
### TrustMate (Review Invitations)
|
||
- **Type**: Browser-based (requires JS execution)
|
||
- **Code**: `cron.php` (line ~741), `cron-trustmate.php`
|
||
- **Config**: `$config['trustmate']['enabled']`
|
||
|
||
### Google Shopping Feed
|
||
- **Type**: XML feed generation
|
||
- **Cron job**: `GOOGLE_XML_FEED`
|
||
- **Code**: `cron.php` → `ProductRepository::generateGoogleFeedXml()`
|
||
|
||
### shopPRO Product Import
|
||
- **Type**: Direct MySQL connection to remote shopPRO instance
|
||
- **Config**: `pp_shop_shoppro_settings` (domain, db credentials)
|
||
- **Code**: `IntegrationsRepository.php` (lines 668–850)
|
||
- **Logs**: `/logs/shoppro-import-debug.log`
|
||
|
||
### REST API (ordersPRO — outbound)
|
||
- **Auth**: `X-Api-Key` header
|
||
- **Endpoints**: orders (list/get/status/paid), products (list/get), dictionaries, categories
|
||
- **Code**: `api.php` → `autoload/api/ApiRouter.php` → `autoload/api/Controllers/`
|
||
|
||
## Cron Job System
|
||
|
||
| Job Type | Purpose |
|
||
|----------|---------|
|
||
| `APILO_TOKEN_KEEPALIVE` | OAuth token refresh |
|
||
| `APILO_SEND_ORDER` | Sync orders to Apilo (priority 40) |
|
||
| `APILO_SYNC_PAYMENT` | Sync payment status |
|
||
| `APILO_STATUS_POLL` | Poll order status changes |
|
||
| `APILO_PRODUCT_SYNC` | Update product qty & prices |
|
||
| `APILO_PRICELIST_SYNC` | Update pricelist |
|
||
| `PRICE_HISTORY` | Record price history |
|
||
| `ORDER_ANALYSIS` | Order/product correlation |
|
||
| `TRUSTMATE_INVITATION` | Review invitations |
|
||
| `GOOGLE_XML_FEED` | Google Shopping XML |
|
||
|
||
- **Priority levels**: CRITICAL(10), HIGH(50), NORMAL(100), LOW(200)
|
||
- **Backoff**: Exponential on failure (60s → 3600s max)
|
||
- **Storage**: `pp_cron_jobs` table
|