Dodano mapę kodu w .paul/codebase/ (7 dokumentów)
Wygenerowano przez równoległą analizę czterech agentów: stack, architektura, konwencje, integracje, testy, baza danych oraz wykryte problemy i dług techniczny. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
126
.paul/codebase/architecture.md
Normal file
126
.paul/codebase/architecture.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Architecture — rank24.pl
|
||||
|
||||
## Pattern
|
||||
Custom PHP MVC — no framework. Layered as **controls → factory → view**, with Savant3 templates.
|
||||
|
||||
## Entry Points
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `index.php` | Front controller — bootstraps app, routes all page requests |
|
||||
| `ajax.php` | xajax AJAX endpoint |
|
||||
| `json.php` | JSON responses for AJAX calls |
|
||||
| `api.php` | External API integration endpoint |
|
||||
| `cron.php` | Background job runner |
|
||||
| `proxy.php` | Proxy management endpoint |
|
||||
| `ajax-check.php` | Health check / secondary AJAX |
|
||||
| `dsf.php` | DataForSEO callback handler |
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
rank24.pl/
|
||||
├── index.php Front controller & bootstrap
|
||||
├── config.php All configuration (DB, proxy, intervals)
|
||||
├── cron.php Cron job runner
|
||||
├── .htaccess URL rewriting rules
|
||||
│
|
||||
├── autoload/ PSR-0-style autoloaded classes
|
||||
│ ├── class.*.php Core utility classes
|
||||
│ ├── controls/ Page controllers (routing + business logic)
|
||||
│ ├── factory/ Data access layer (DB queries via Medoo)
|
||||
│ ├── view/ View renderers (build Savant3 template output)
|
||||
│ ├── savant3/ Savant3 template engine internals
|
||||
│ └── opd*/ Legacy PDO debug wrapper
|
||||
│
|
||||
├── templates/ PHP view templates
|
||||
│ ├── page/ Admin main/unlogged layouts
|
||||
│ ├── client/ Client dashboard templates
|
||||
│ ├── ranker/ Admin/ranker management templates
|
||||
│ ├── reseller/ Reseller dashboard templates
|
||||
│ ├── html/ Reusable form component templates
|
||||
│ ├── other/ Pagination, alerts, misc templates
|
||||
│ └── cron/ Cron management view
|
||||
│
|
||||
├── functions/ xajax AJAX handler functions
|
||||
│ ├── xajax.php xajax init & config
|
||||
│ ├── xajax-ranker.php Rank-related AJAX
|
||||
│ ├── xajax-messages.php Messaging AJAX
|
||||
│ ├── xajax-analysis.php Analysis AJAX
|
||||
│ └── xajax-settings.php Settings AJAX
|
||||
│
|
||||
├── libraries/ Third-party libraries
|
||||
│ ├── medoo.php ORM
|
||||
│ ├── grid/ Custom DataTables grid
|
||||
│ └── framework/ Bootstrap + jQuery + 57 plugins
|
||||
│
|
||||
├── layout/ Static assets, compiled CSS
|
||||
├── resources/ xajax, phpmailer, mPDF
|
||||
└── temp/, temp_t/ File cache directories
|
||||
```
|
||||
|
||||
## Autoloading
|
||||
|
||||
Defined in `index.php`:
|
||||
```php
|
||||
// namespace\ClassName → autoload/namespace/class.ClassName.php
|
||||
// ClassName → autoload/class.ClassName.php
|
||||
spl_autoload_register('__autoload_my_classes');
|
||||
```
|
||||
|
||||
## Request Flow
|
||||
|
||||
```
|
||||
HTTP request
|
||||
→ .htaccess: rewrites /m/a/params → ?module=m&action=a¶ms
|
||||
→ index.php: load config, init $db (OPD) + $mdb (Medoo), start session, init $cache
|
||||
→ \controls\Page::checkUrlParams() (handles ?rw= special actions)
|
||||
→ \controls\Page::getContent() (resolves module+action → controller class)
|
||||
→ \controls\[Module]::method() (business logic, calls factory)
|
||||
→ \factory\[Module]::query() (Medoo DB queries)
|
||||
→ \view\[Module]::render() (assigns data to Savant3, returns HTML)
|
||||
→ \view\Page::show() (wraps in role-appropriate layout)
|
||||
→ HTML → browser
|
||||
```
|
||||
|
||||
## User Roles & Routing
|
||||
|
||||
| Role | Source table | Layout |
|
||||
|------|-------------|--------|
|
||||
| `admin` | `pro_users` | `templates/page/main-layout.php` |
|
||||
| `client` | `pro_rr_clients` (type=0) | `templates/client/main-layout.php` |
|
||||
| `worker` | `pro_rr_clients` (type=2) | `templates/client/main-layout.php` |
|
||||
| `reseller` | `pro_rr_clients` (type=1) | `templates/reseller/main-layout.php` |
|
||||
|
||||
## Template System
|
||||
|
||||
Two systems co-exist:
|
||||
|
||||
**Savant3** (primary): `$tpl = new \Savant3; $tpl->varName = $val; return $tpl->fetch('ranker/summary');`
|
||||
|
||||
**Tpl** (lightweight): `$tpl = new \Tpl; $tpl->render('other/pager');`
|
||||
- Template search order: `templates_a/` → `templates_b/` → `templates/`
|
||||
|
||||
## Database Layer
|
||||
|
||||
Two connections initialized in `index.php`:
|
||||
- `$db` — OPD (legacy PDO debug wrapper), used in older code paths
|
||||
- `$mdb` — Medoo ORM, used in all newer code
|
||||
|
||||
Factory pattern: controllers call `\factory\Ranker::getClient($id)` which does `global $mdb; return $mdb->get(...)`.
|
||||
|
||||
## Cron System
|
||||
|
||||
`cron.php` → `\Cron::staticMethod()` — jobs defined as static methods in `autoload/class.Cron.php`:
|
||||
- `fill_missing_positions()` — interpolates missing rank records
|
||||
- `archive_positions()` / `archive_empty()` — data archiving
|
||||
- `check_proxy()` — validates proxy pool
|
||||
- `get_phrases_positions_dfs3()` / `post_phrases_positions_dfs3()` — DataForSEO rank fetching
|
||||
|
||||
## AJAX System
|
||||
|
||||
`functions/xajax.php` registers handler functions → `ajax.php` processes incoming xajax requests → returns DOM update commands to jQuery on client.
|
||||
|
||||
## Caching
|
||||
|
||||
`\FileCache` stores serialized data in `temp/` and `temp_t/`. Invalidated via `\S::deleteCache()`.
|
||||
97
.paul/codebase/concerns.md
Normal file
97
.paul/codebase/concerns.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Concerns & Technical Debt — rank24.pl
|
||||
|
||||
## Security — CRITICAL
|
||||
|
||||
### Hardcoded Credentials (must fix before any public exposure)
|
||||
|
||||
| Secret | Location | Risk |
|
||||
|--------|---------|------|
|
||||
| MySQL password | `config.php` lines 2-5 | Full DB access if repo leaked |
|
||||
| FTP password | `.vscode/ftp-kr.json`, `.vscode/sftp.json` | Full server access |
|
||||
| DataForSEO API key | `autoload/class.Cron.php` ~lines 160, 262, 354 | API abuse / billing fraud |
|
||||
| SMTP password | `autoload/class.S.php` ~lines 293-300 | Email spoofing |
|
||||
|
||||
**Remediation**: move all secrets to environment variables or a `.env` file excluded from VCS.
|
||||
|
||||
### SQL Injection
|
||||
|
||||
- `autoload/class.Cron.php` ~line 200: raw string concatenation in DELETE query
|
||||
- `autoload/class.GoogleRank.php` lines 74, 96, 100, 136, 158, 162: raw string concat in UPDATE queries
|
||||
- `autoload/class.DataBase.php` lines 15, 47, 82: mixed OPD with string building
|
||||
|
||||
**Remediation**: use Medoo's parameterized methods or PDO `bindValue()` for all dynamic values.
|
||||
|
||||
### Other Security Issues (MEDIUM)
|
||||
|
||||
- **Weak password hashing**: `md5($pass1)` in `autoload/class.DataBase.php` line 31 — use `password_hash()`
|
||||
- **No CSRF protection**: state-changing AJAX operations in `ajax.php` lack CSRF tokens
|
||||
- **Path traversal**: `autoload/class.DataBase.php` ~line 57 — user-supplied `image_folder` concatenated into file path without validation
|
||||
- **Client-supplied MIME type**: file type validation in `class.DataBase.php` checks `$file['type']` (attacker-controlled)
|
||||
- **Insecure deserialization**: `@unserialize()` used in `autoload/class.FileCache.php` line 43 and `autoload/opd.statement.php`
|
||||
- **XSS**: `\S::get()` reads raw `$_POST`/`$_GET` without sanitization; values reach HTML output in multiple templates
|
||||
|
||||
## Technical Debt
|
||||
|
||||
### God Classes
|
||||
|
||||
- `autoload/class.S.php` — 700+ lines; handles sessions, email, DNS, CSV, URL, string utils, DB helpers. Should be split.
|
||||
- `autoload/class.GoogleRank.php` — 300+ lines; proxy selection logic repeated 4+ times with no extraction.
|
||||
- `autoload/class.Cron.php` — 400+ lines; hardcoded credentials, multiple large functions.
|
||||
|
||||
### Code Duplication
|
||||
|
||||
- Proxy selection + backoff UPDATE query repeated verbatim ~4 times in `class.GoogleRank.php`
|
||||
- Google block-detection strings (`"Our systems have detected unusual traffic"`) duplicated in multiple methods
|
||||
|
||||
### Global State Anti-Pattern
|
||||
|
||||
Every class does `global $db, $mdb, $user, $config, $cache;` — no DI, no service container. Makes refactoring and testing very difficult.
|
||||
|
||||
### Two ORM Layers
|
||||
|
||||
Both `$db` (OPD) and `$mdb` (Medoo) are initialized and used. Older code paths use OPD raw queries; newer paths use Medoo. Inconsistent access patterns throughout.
|
||||
|
||||
### Deprecated PHP Patterns
|
||||
|
||||
- Old-style constructor: `function DataEdit()` in `autoload/class.DataEdit.php` line 32 (should be `__construct()`)
|
||||
- `global` variable injection instead of constructor parameters
|
||||
- Short open tags `<?` in templates — requires `short_open_tag = On` in php.ini
|
||||
|
||||
### Missing Abstractions
|
||||
|
||||
- No HTTP client wrapper — cURL used directly in `class.GoogleScraper.php`, no retry/logging
|
||||
- No proxy manager class — proxy logic spread across `GoogleRank`, `GoogleSite`, `class.S`
|
||||
- No logger — debugging done via `file_put_contents('google-rank.txt', ...)` and commented-out `\S::pre()`
|
||||
- No centralized input validation layer — all `\S::get()` calls are point-of-use
|
||||
|
||||
## Reliability Concerns
|
||||
|
||||
### Cron Jobs
|
||||
|
||||
- No retry logic — single failure = job skipped until next run
|
||||
- No max execution time enforcement — long foreach loops can time out silently
|
||||
- `cron.php` outputs JSON directly — no structured logging for cron daemon
|
||||
- API responses partially unchecked: `class.Cron.php` ~line 162 returns `'ok'` without verifying data integrity
|
||||
|
||||
### Scraping / Proxy
|
||||
|
||||
- Proxy rotation is deterministic (`ORDER BY used ASC LIMIT 1`) — predictable, easier for Google to detect
|
||||
- No rate limiting or delays between requests in batch operations
|
||||
- No exponential backoff — same fixed 10s timeout regardless of failure history (`CURLOPT_TIMEOUT = 10`)
|
||||
- Block detection only covers known string patterns — new CAPTCHA formats would be missed
|
||||
- `file_put_contents('google-rank.txt', $result)` in `class.GoogleRank.php` line ~185 — debug log left in production
|
||||
|
||||
### Error Handling
|
||||
|
||||
- Global `error_reporting` suppresses notices, warnings, deprecations — real errors can be masked
|
||||
- cURL operations in `class.GoogleScraper.php` have no try/catch — silent failures return `-1`
|
||||
- File operations in `class.DataBase.php` use `@` suppression — orphaned temp files possible
|
||||
- No circuit breaker — scraping continues even after repeated proxy failures
|
||||
|
||||
## Minor Issues
|
||||
|
||||
- Debug variable `$debbbb` left in `autoload/class.S.php` line ~357
|
||||
- Commented-out dead code in `autoload/class.Cron.php` lines 56-61
|
||||
- Duplicate key in array: `autoload/class.Cron.php` lines ~364, ~376 — `'se_id'` set twice with different values
|
||||
- Session-based state won't scale to multi-server deployment (no session locking)
|
||||
- All proxy requests use `http://` (line ~120 `class.GoogleRank.php`) — credentials sniffable on network
|
||||
77
.paul/codebase/conventions.md
Normal file
77
.paul/codebase/conventions.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Conventions — rank24.pl
|
||||
|
||||
## PHP Naming
|
||||
|
||||
| Element | Convention | Example |
|
||||
|---------|-----------|---------|
|
||||
| Class files | `class.ClassName.php` | `class.GoogleRank.php` |
|
||||
| Class names | PascalCase | `GoogleScraper`, `FileCache` |
|
||||
| Namespaces | lowercase | `controls\`, `factory\`, `view\` |
|
||||
| Public methods | camelCase | `SaveData()`, `getpagedata()` |
|
||||
| Private properties | underscore + camelCase | `$_table`, `$_proxy`, `$_header` |
|
||||
| Local variables | snake_case | `$db_edit_table`, `$last_id` |
|
||||
| Config keys | snake_case | `$config['db']['host']` |
|
||||
|
||||
## File Naming
|
||||
|
||||
- Class files: `class.ClassName.php` in `autoload/` subdirectory matching namespace
|
||||
- Templates: lowercase with hyphens — `main-layout.php`, `site-edit.php`
|
||||
- Entry points: lowercase — `index.php`, `ajax.php`, `cron.php`
|
||||
- Directories: lowercase — `autoload/`, `templates/`, `libraries/`
|
||||
|
||||
## Code Style
|
||||
|
||||
- **Indentation**: 2 spaces
|
||||
- **Braces**: K&R — opening brace on same line for control structures; new line for methods
|
||||
- **Spacing**: spaces around `->`, `=`, `=>` operators; spaces inside `( )` for function calls
|
||||
- **Arrays**: mix of long `array()` in config, short `[]` in Medoo queries
|
||||
- **Short PHP tags**: templates use `<?` and `<?=` (not `<?php`)
|
||||
- **No type hints**: no PHP type declarations used anywhere
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Global error suppression in `index.php`:
|
||||
```php
|
||||
error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED);
|
||||
```
|
||||
- User alerts via `\S::alert('message')` — stored in session, displayed on next render
|
||||
- Very limited try/catch; exceptions only in OPD wrapper (`opd.class.php`)
|
||||
- File/curl errors frequently suppressed with `@` operator
|
||||
|
||||
## Database Conventions
|
||||
|
||||
- **New code**: use Medoo (`$mdb`), array-based query syntax
|
||||
- **Legacy code**: use OPD (`$db`), PDO `prepare()` + `execute()`
|
||||
- Table names: `pro_` prefix (e.g., `pro_rr_clients`, `pro_proxy_servers`)
|
||||
- All factory methods access DB via `global $mdb;`
|
||||
|
||||
## Configuration Access
|
||||
|
||||
- All config in `config.php` as `$config['section']['key']` array
|
||||
- Classes access via `global $config;`
|
||||
- No `.env` files, no constants for settings (only `OPD_DIR`, `OPD_VERSION`)
|
||||
|
||||
## Comments & Docs
|
||||
|
||||
- Comments are sparse and in **Polish**
|
||||
- No docblocks on most classes/methods (exception: `RestClient3.php`)
|
||||
- Inline comments explain "why" only — rare but present
|
||||
|
||||
## Global State
|
||||
|
||||
Classes depend on globals declared at bootstrap:
|
||||
```php
|
||||
global $db, $mdb, $lang, $sys, $user, $cache, $config, $settings;
|
||||
```
|
||||
No dependency injection. No service container.
|
||||
|
||||
## Template Conventions
|
||||
|
||||
- Savant3 templates receive variables as `$this->varName`
|
||||
- Tpl templates receive variables as assigned properties, accessed in template scope
|
||||
- HTML helper components in `templates/html/` — generated via `\Html::form_text()`, `\Html::select()`, etc.
|
||||
- All UI strings use Polish language
|
||||
|
||||
## Language
|
||||
|
||||
- All user-facing text, comments, variable names, and commit messages are in **Polish**
|
||||
98
.paul/codebase/db_schema.md
Normal file
98
.paul/codebase/db_schema.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Database Schema — rank24.pl
|
||||
|
||||
Database: `host700513_rank24` (MySQL 5.x, charset utf8)
|
||||
|
||||
> This document reflects table names and columns inferred from source code analysis.
|
||||
> For authoritative schema, run: `SHOW CREATE TABLE <table_name>;`
|
||||
|
||||
## Known Tables
|
||||
|
||||
### `pro_users`
|
||||
Admin user accounts.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | int | PK |
|
||||
| `login` | varchar | Username |
|
||||
| `password` | varchar | MD5 hash (legacy) |
|
||||
| `type` | varchar | Role: `admin` |
|
||||
|
||||
### `pro_rr_clients`
|
||||
Client, reseller, and worker accounts.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | int | PK |
|
||||
| `login` | varchar | |
|
||||
| `password` | varchar | MD5 hash |
|
||||
| `type` | int | 0=client, 1=reseller, 2=worker |
|
||||
| `active` | int | |
|
||||
| `reseller_id` | int | FK to self (reseller parent) |
|
||||
|
||||
### `pro_proxy_servers`
|
||||
HTTP proxy pool for scraping.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | int | PK |
|
||||
| `proxy` | varchar | `ip:port` |
|
||||
| `bg` | int | Ban/backoff counter |
|
||||
| `bgd` | datetime | Backoff until datetime |
|
||||
| `used` | datetime | Last used timestamp |
|
||||
| `enabled` | int | 1=active, 0=disabled |
|
||||
|
||||
### `pro_rr_sites`
|
||||
Monitored websites per client.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | int | PK |
|
||||
| `client_id` | int | FK → `pro_rr_clients.id` |
|
||||
| `url` | varchar | Domain / URL |
|
||||
| `active` | int | |
|
||||
|
||||
### `pro_rr_sites_majestic`
|
||||
Majestic metrics cache per site.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `site_id` | int | FK → `pro_rr_sites.id` |
|
||||
| `trust_flow` | int | |
|
||||
| `citation_flow` | int | |
|
||||
| `external_backlinks` | int | |
|
||||
| `ref_domains` | int | |
|
||||
| `updated_at` | datetime | |
|
||||
|
||||
### `phrase_positions_statistic`
|
||||
Live ranking data (rolling 2 years).
|
||||
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | int | PK |
|
||||
| `phrase_id` | int | FK → phrases table |
|
||||
| `date` | date | |
|
||||
| `position` | int | Google rank position |
|
||||
| `url` | varchar | Result URL |
|
||||
|
||||
### `phrase_positions_archive`
|
||||
Archived ranking data (older than 2 years).
|
||||
|
||||
Same structure as `phrase_positions_statistic`.
|
||||
|
||||
## Table Name Patterns
|
||||
|
||||
All application tables use the `pro_` prefix:
|
||||
- `pro_users` — admin users
|
||||
- `pro_rr_clients` — clients / resellers / workers
|
||||
- `pro_rr_sites` — tracked sites
|
||||
- `pro_rr_sites_majestic` — Majestic metrics
|
||||
- `pro_proxy_servers` — proxy pool
|
||||
- `phrase_positions_statistic` — live positions (no prefix — legacy naming)
|
||||
- `phrase_positions_archive` — archived positions
|
||||
|
||||
## Notes
|
||||
|
||||
- Passwords stored as **MD5** — upgrade to `password_hash()` / `password_verify()` is a known debt item
|
||||
- Positions older than 2 years are moved from `phrase_positions_statistic` → `phrase_positions_archive` by `\Cron::archive_positions()`
|
||||
- Missing positions (gaps in daily records) are interpolated by `\Cron::fill_missing_positions()`
|
||||
- Proxy backoff: `bgd = NOW() + (bg * 15 MINUTE)` where `bg` increments on each failure
|
||||
72
.paul/codebase/integrations.md
Normal file
72
.paul/codebase/integrations.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# External Integrations — rank24.pl
|
||||
|
||||
## DataForSEO API (Primary — Active)
|
||||
|
||||
- **Purpose**: Google SERP rank checking — replaces direct Google scraping
|
||||
- **Client v2**: `autoload/RestClient.php`
|
||||
- **Client v3**: `autoload/RestClient3.php`
|
||||
- **Credentials**: hardcoded in `autoload/class.Cron.php` (lines ~160, ~262, ~354) — `pyziak84@gmail.com`
|
||||
- **Usage**: `\Cron::post_phrases_positions_dfs3()` submits tasks; `\Cron::get_phrases_positions_dfs3()` retrieves results
|
||||
- **Auth**: HTTP Basic Auth over HTTPS
|
||||
|
||||
## Majestic (Active)
|
||||
|
||||
- **Purpose**: Domain authority metrics — TF (Trust Flow), CF (Citation Flow), backlinks, RefDomains
|
||||
- **Data stored in**: `pro_rr_sites_majestic` table
|
||||
- **Refresh interval**: `$config['site']['majestic_interval']` = 7 days
|
||||
- **Integration point**: `api.php` + relevant factory methods
|
||||
|
||||
## SEMstorm (Active)
|
||||
|
||||
- **Purpose**: Keyword traffic / visibility data
|
||||
- **Refresh interval**: `$config['site']['semstorm_interval']` = 1 day
|
||||
- **Integration point**: `api.php`
|
||||
|
||||
## Proxy Providers (Disabled)
|
||||
|
||||
| Provider | API endpoint (stored in config) | Config key | Status |
|
||||
|---------|-------------------------------|-----------|--------|
|
||||
| ProxyMarket | `http://www.proxymarket.pl/api/get/...` | `proxymarket-api` | disabled |
|
||||
| Proxy.Adding.pl | `http://proxy.adding.pl/apiproxy/...` | `adding-api` | disabled |
|
||||
|
||||
Active proxies are managed internally in the `pro_proxy_servers` DB table.
|
||||
|
||||
## Internal Proxy Pool
|
||||
|
||||
- **Table**: `pro_proxy_servers` (columns: `id`, `proxy`, `bg`, `bgd`, `used`, `enabled`)
|
||||
- **Rotation logic**: `ORDER BY used ASC LIMIT 1` (least-recently-used)
|
||||
- **Backoff**: failed proxy gets `bgd = NOW() + (bg * 15 minutes)` cooldown
|
||||
- **Validation**: `\Cron::check_proxy()` pings each proxy, marks invalid ones disabled
|
||||
- **Config**: `$config['proxy']['sv-check']` = 2, `$config['proxy']['ht-check']` = 4, `$config['proxy']['s-version']` = 1.218
|
||||
|
||||
## Direct Google Scraping (Legacy — still in codebase)
|
||||
|
||||
- **Classes**: `autoload/class.GoogleScraper.php`, `autoload/class.GoogleRank.php`, `autoload/class.GoogleSite.php`
|
||||
- `GoogleScraper` — cURL-based scraper with 24 rotating user agents, proxy support, cookie handling
|
||||
- `GoogleRank` — orchestrates proxy selection → scrape → parse position → store result
|
||||
- Block detection: checks for `"Our systems have detected unusual traffic"`, `"Forbidden"`, etc.
|
||||
- Status: likely superseded by DataForSEO but classes remain
|
||||
|
||||
## PHPMailer / SMTP Email
|
||||
|
||||
- **Library**: `resources/phpmailer/` (v5.2.15)
|
||||
- **Credentials**: SMTP hardcoded in `autoload/class.S.php` (lines ~293-300) — `biuro@project-pro.pl`
|
||||
- **Usage**: transactional emails, notifications, organizer email: `poczta@project-dc.pl`
|
||||
|
||||
## mPDF — PDF Reports
|
||||
|
||||
- **Library**: `resources/mpdf60/` (v6.0)
|
||||
- **Usage**: PDF report generation, rendered via `templates/*/reports-pdf.php`
|
||||
|
||||
## xajax — AJAX Framework
|
||||
|
||||
- **Library**: `resources/xajax/`
|
||||
- **Handler files**: `functions/xajax-*.php`
|
||||
- **Entry point**: `ajax.php`
|
||||
|
||||
## FTP/SFTP Deployment
|
||||
|
||||
- **Tool**: VS Code FTP-KR extension
|
||||
- **Host**: `host700513.hostido.net.pl`
|
||||
- **Remote path**: `/public_html/`
|
||||
- **Config files**: `.vscode/ftp-kr.json`, `.vscode/sftp.json` (credentials stored in plaintext)
|
||||
55
.paul/codebase/stack.md
Normal file
55
.paul/codebase/stack.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Stack — rank24.pl
|
||||
|
||||
## Core Language & Runtime
|
||||
- **PHP** (5.6+, no version pinned) — backend logic, no framework
|
||||
- **MySQL 5.x** — primary data store (host: `localhost`, db: `host700513_rank24`)
|
||||
- **Apache** with `mod_rewrite` — URL rewriting via `.htaccess`
|
||||
- **Timezone**: `Europe/Warsaw`, encoding: `UTF-8`
|
||||
|
||||
## PHP Libraries
|
||||
|
||||
| Library | Version | Purpose | Path |
|
||||
|---------|---------|---------|------|
|
||||
| Medoo | 1.2.1 | ORM / query builder (MySQL) | `libraries/medoo.php` |
|
||||
| Savant3 | — | Template engine | `autoload/Savant3.php` / `autoload/savant3/` |
|
||||
| OPD (opdClass) | — | Legacy PDO wrapper with debug console | `autoload/opd.class.php` |
|
||||
| PHPMailer | 5.2.15 | SMTP email sending | `resources/phpmailer/` |
|
||||
| mPDF | 6.0 | Server-side PDF generation | `resources/mpdf60/` |
|
||||
| xajax | — | Server-side AJAX request handler | `resources/xajax/` |
|
||||
| RestClient | 2.0 | DataForSEO API v2 client | `autoload/RestClient.php` |
|
||||
| RestClient3 | 3.0 | DataForSEO API v3 client | `autoload/RestClient3.php` |
|
||||
| Custom Grid | — | DataTables-based grid (view/edit/upload) | `libraries/grid/` |
|
||||
|
||||
## Frontend Stack
|
||||
|
||||
| Library | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| jQuery | 1.11.1 | DOM / AJAX | `libraries/framework/vendor/jquery/` |
|
||||
| Bootstrap | 3.x | CSS framework, JS components | `libraries/framework/` |
|
||||
| DataTables | — | Sortable/filterable tables | `libraries/framework/vendor/plugins/` |
|
||||
| CKEditor | — | Rich text editing | `libraries/framework/vendor/plugins/` |
|
||||
| Highcharts / C3 | — | Charts and data viz | `libraries/framework/vendor/plugins/` |
|
||||
| Moment.js | — | Date manipulation | `libraries/framework/vendor/plugins/` |
|
||||
| Select2 | — | Searchable selects | `libraries/framework/vendor/plugins/` |
|
||||
| Dropzone | — | Drag-and-drop file uploads | `libraries/framework/vendor/plugins/` |
|
||||
| Font Awesome / Glyphicons | — | Icon fonts | `libraries/framework/` |
|
||||
|
||||
CSS preprocessing via **SCSS/SASS** — source in `layout/style-scss/`, compiled to `layout/style-css/custom.css`.
|
||||
|
||||
## External Service Integrations
|
||||
|
||||
| Service | Purpose | Config key |
|
||||
|---------|---------|-----------|
|
||||
| DataForSEO API v2/v3 | Google rank checking (primary) | credentials in `class.Cron.php` |
|
||||
| Majestic | Domain metrics (TF, CF, backlinks) | `$config['site']['majestic_interval']` = 7d |
|
||||
| SEMstorm | Keyword / traffic data | `$config['site']['semstorm_interval']` = 1d |
|
||||
| ProxyMarket | Proxy provider (disabled) | `$config['proxy']['proxymarket-api']` |
|
||||
| Proxy.Adding.pl | Proxy provider (disabled) | `$config['proxy']['adding-api']` |
|
||||
| Internal proxy pool | HTTP proxies for scraping | table `pro_proxy_servers` |
|
||||
|
||||
## Deployment
|
||||
|
||||
- **FTP/SFTP** to `host700513.hostido.net.pl` — auto-upload via VS Code FTP-KR extension
|
||||
- Remote root: `/public_html/`
|
||||
- Config: `.vscode/ftp-kr.json`, `.vscode/sftp.json`
|
||||
- No CI/CD pipeline; manual or FTP-based deploys only
|
||||
33
.paul/codebase/testing.md
Normal file
33
.paul/codebase/testing.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Testing — rank24.pl
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
**No automated tests exist.** There are no:
|
||||
- PHPUnit configuration files (`phpunit.xml`, `phpunit.xml.dist`)
|
||||
- Test directories (`tests/`, `test/`, `spec/`)
|
||||
- Test class files (`*Test.php`, `*Spec.php`)
|
||||
- CI/CD pipeline that runs tests
|
||||
|
||||
## How Testing Is Done
|
||||
|
||||
All testing is **manual** via the web interface:
|
||||
|
||||
1. **Web UI testing** — load pages in browser, exercise forms and interactions
|
||||
2. **AJAX endpoints** — `ajax-check.php` used for health checks / spot validation
|
||||
3. **Cron output** — `cron.php` returns JSON; check via browser or log inspection
|
||||
4. **PHP error logs** — `error_reporting` is suppressed in production; errors must be caught via server logs or temporary enabling of reporting
|
||||
|
||||
## Debugging Aids
|
||||
|
||||
- **OPD debug console** — `$config['db']['debug']` enables query logging via `opd.debug.php`
|
||||
- **`\S::pre()`** — utility for dumping variables (calls `var_dump` / `print_r`), used inline and commented out: `//\S::pre($results); exit;`
|
||||
- **`file_put_contents('google-rank.txt', $result)`** — ad-hoc scraping debug log in `class.GoogleRank.php`
|
||||
- **`$debbbb = $data`** — debug variable left in `class.S.php`
|
||||
|
||||
## Adding Tests (Guidance for Future)
|
||||
|
||||
If automated testing is introduced:
|
||||
- PHPUnit is the natural choice for PHP
|
||||
- Heavy global state (`$db`, `$mdb`, `$user`) makes unit testing hard without refactoring — start with integration tests against a test database
|
||||
- Factory classes (`factory\*`) are the best seam for testing — they have clear input/output and centralize DB access
|
||||
- Cron methods in `class.Cron.php` return `['status' => 'ok'|'empty', 'msg' => '...']` — easily assertable
|
||||
Reference in New Issue
Block a user