- 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.
6.1 KiB
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 (
$mdbglobal) 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()) orecho json_encode()+exitfor AJAX.autoload/factory/— Data access layer. Static methods wrapping$mdbqueries. 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 byTpl::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', [...])renderstemplates/module/template.php. Looks intemplates_user/first (override), thentemplates/.\DbModel— Active Record base class. Subclasses set$table; providessave(),delete().\Cache— File-based cache intemp/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:
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([...])thenexit - Page actions: return HTML string from
\Tpl::view() - POST/GET params: always use
\S::get('param_name'), never$_POST/$_GETdirectly - Flash messages:
\S::alert('message')thenheader('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
- Create controller:
autoload/controls/class.{ModuleName}.php(namespacecontrols) - Create factory:
autoload/factory/class.{ModuleName}.php(namespacefactory) - Optionally create view helper:
autoload/view/class.{ModuleName}.php(namespaceview) - Create templates:
templates/{module_name}/main_view.phpetc. - Add route aliases in
index.php$route_aliasesarray if clean URLs are needed - 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 legacyapi.php,cron.php)phpmailer/— Email sendingframework/— jQuery UI, Bootstrap, various jQuery pluginsfunctions.js— Shared JS utilitiesadspro-dialog.js/.css— Custom modal dialog component