- Implemented the main view for Supplemental Feeds, displaying clients with Merchant Account IDs and their associated feed files. - Added styling for the feeds page and its components, including headers, empty states, and dropdown menus for syncing actions. - Created backend logic to generate supplemental feeds for clients, including file handling and data sanitization. - Integrated new routes and views for managing feeds, ensuring proper data retrieval and display. - Updated navigation to include the new Supplemental Feeds section. - Added necessary documentation for CRON job management related to feed generation.
118 lines
6.1 KiB
Markdown
118 lines
6.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
adsPRO is a PHP web application for managing Google Ads, Facebook Ads, and Google Merchant Center campaigns. It tracks campaign performance (ROAS, budgets, conversions), manages product feeds, and provides AI-powered suggestions for product titles/descriptions. The UI is in Polish.
|
|
|
|
## Tech Stack
|
|
|
|
- **PHP** (no framework, custom MVC-like architecture)
|
|
- **MySQL** via Medoo ORM (`$mdb` global) and RedBeanPHP (`\R::`) in legacy endpoints
|
|
- **Frontend**: jQuery, DataTables, Highcharts, Select2, Bootstrap 5, Font Awesome 6
|
|
- **SCSS** for styling (`layout/style.scss` → `layout/style.css`)
|
|
- **Google Ads REST API** v23 (direct cURL, no SDK)
|
|
- **Facebook Ads Graph API** (direct cURL)
|
|
- **AI services**: OpenAI, Claude, Gemini APIs for product text suggestions
|
|
|
|
## Architecture
|
|
|
|
### Request Flow
|
|
|
|
`index.php` is the single entry point. `.htaccess` rewrites all non-static requests to it. The router uses a `$route_aliases` map and fallback URL segment parsing (`/module/action`) to set `$_GET['module']` and `$_GET['action']`. `\controls\Site::route()` instantiates `\controls\{Module}` and calls the action method.
|
|
|
|
Other entry points:
|
|
- `ajax.php` — AJAX requests (same autoloader, session-based auth with IP binding)
|
|
- `api.php` — external API endpoints (domain tester, Open Page Rank)
|
|
- `cron.php` — legacy cron (task reminders, recurring tasks)
|
|
|
|
### Autoloader & Namespace Convention
|
|
|
|
`spl_autoload_register` maps namespaces to filesystem paths:
|
|
- `\controls\Campaigns` → `autoload/controls/class.Campaigns.php`
|
|
- `\factory\Clients` → `autoload/factory/class.Clients.php`
|
|
- `\services\GoogleAdsApi` → `autoload/services/class.GoogleAdsApi.php`
|
|
- `\view\Site` → `autoload/view/class.Site.php`
|
|
|
|
File naming: `class.{ClassName}.php`. Root-level classes (no namespace): `autoload/class.{Name}.php`.
|
|
|
|
### Layer Responsibilities
|
|
|
|
- **`autoload/controls/`** — Controllers. Handle request params via `\S::get()`, call factory/services, return HTML (via `\Tpl::view()`) or `echo json_encode()` + `exit` for AJAX.
|
|
- **`autoload/factory/`** — Data access layer. Static methods wrapping `$mdb` queries. Named after domain entities (Clients, Campaigns, Products, etc.).
|
|
- **`autoload/services/`** — External API integrations (GoogleAdsApi, FacebookAdsApi, ClaudeApi, OpenAiApi, GeminiApi, SupplementalFeed).
|
|
- **`autoload/view/`** — View helpers. Thin wrappers that call `\Tpl::view()` with template path and data.
|
|
- **`templates/{module}/`** — PHP template files rendered by `Tpl::view()`. Templates access data via `$this->varName`.
|
|
|
|
### Key Base Classes
|
|
|
|
- **`\S`** — Static utility: `get()` reads POST/GET, `get_session()`/`set_session()` for sessions, `alert()` for flash messages, `send_email()` for SMTP.
|
|
- **`\Tpl`** — Template engine. `Tpl::view('module/template', [...])` renders `templates/module/template.php`. Looks in `templates_user/` first (override), then `templates/`.
|
|
- **`\DbModel`** — Active Record base class. Subclasses set `$table`; provides `save()`, `delete()`.
|
|
- **`\Cache`** — File-based cache in `temp/` directory. `Cache::store($key, $data, $ttl)` / `Cache::fetch($key)`.
|
|
|
|
### Settings Storage
|
|
|
|
App settings (API keys, cron state, feature flags) are stored in a `settings` DB table as key-value pairs. Access via `\services\GoogleAdsApi::get_setting($key)` / `set_setting($key, $value)` — these are used globally, not just for Google Ads.
|
|
|
|
## Database Migrations
|
|
|
|
Numbered SQL files in `migrations/` (e.g., `001_google_ads_settings.sql`). Run via:
|
|
|
|
```bash
|
|
php install.php # apply pending migrations
|
|
php install.php --force # re-apply all migrations
|
|
php install.php --with_demo # include demo_data.sql
|
|
```
|
|
|
|
Tracks applied migrations in `schema_migrations` table.
|
|
|
|
## Cron System
|
|
|
|
Multiple cron endpoints called externally (e.g., every 1-5 minutes):
|
|
|
|
| Endpoint | Purpose |
|
|
|---|---|
|
|
| `/cron.php` | Legacy: task reminders, recurring tasks |
|
|
| `/cron/cron_universal` | Google Ads campaigns + products sync (backfill window) |
|
|
| `/cron/cron_campaigns_product_alerts_merchant` | Product alerts from Merchant Center |
|
|
| `/cron/cron_products_urls` | Fetch product URLs from Merchant Center |
|
|
| `/cron/cron_facebook_ads` | Facebook Ads sync (30-day window) |
|
|
|
|
Progress is tracked in `cron_sync_status` table with phases (pending → fetch → aggregate_30 → done). Dashboard at `/settings` shows real-time progress with ETA calculations.
|
|
|
|
## Supplemental Feeds
|
|
|
|
`\services\SupplementalFeed::generate_for_client($id)` generates TSV files in `feeds/` directory (e.g., `feeds/supplemental_1.tsv`) for Google Merchant Center. Managed via `/feeds` UI.
|
|
|
|
## Coding Conventions
|
|
|
|
- All classes use static methods extensively
|
|
- Database access uses the global `$mdb` (Medoo instance) — never instantiate a new connection
|
|
- AJAX endpoints: `echo json_encode([...])` then `exit`
|
|
- Page actions: return HTML string from `\Tpl::view()`
|
|
- POST/GET params: always use `\S::get('param_name')`, never `$_POST`/`$_GET` directly
|
|
- Flash messages: `\S::alert('message')` then `header('Location: ...')` + `exit`
|
|
- Timezone: `Europe/Warsaw`
|
|
- Currency display: `\S::number_display($value)` formats as "1 234,56 zł"
|
|
- All user-facing strings are in Polish
|
|
|
|
## Adding a New Module
|
|
|
|
1. Create controller: `autoload/controls/class.{ModuleName}.php` (namespace `controls`)
|
|
2. Create factory: `autoload/factory/class.{ModuleName}.php` (namespace `factory`)
|
|
3. Optionally create view helper: `autoload/view/class.{ModuleName}.php` (namespace `view`)
|
|
4. Create templates: `templates/{module_name}/main_view.php` etc.
|
|
5. Add route aliases in `index.php` `$route_aliases` array if clean URLs are needed
|
|
6. Add sidebar link in `templates/site/layout-logged.php`
|
|
|
|
## Frontend Libraries (in `libraries/`)
|
|
|
|
- `medoo/` — Medoo PHP database framework (SQL builder)
|
|
- `rb.php` — RedBeanPHP ORM (used in legacy `api.php`, `cron.php`)
|
|
- `phpmailer/` — Email sending
|
|
- `framework/` — jQuery UI, Bootstrap, various jQuery plugins
|
|
- `functions.js` — Shared JS utilities
|
|
- `adspro-dialog.js/.css` — Custom modal dialog component
|