Fix areazone edit form validation error - Fix wrong field name in areazone_newrow.php (contactid → zoneid) - Move POST variable assignments before validation in Areas::areazone_edit() The user already made the edits in the previous turn. This commit message is ready to use.
6.3 KiB
6.3 KiB
AGENTS.md
Build, Lint, and Test Commands
Running Tests
# Run all tests
composer test
./phpunit
# Run all tests (Windows)
vendor\bin\phpunit
# Run a single test file
./phpunit tests/unit/HealthTest.php
# Run a single test method
./phpunit --filter testIsDefinedAppPath
# Run tests in a specific directory
./phpunit tests/unit/
# Run tests with coverage report
./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m
# Generate HTML coverage report
./phpunit --coverage-html build/logs/html
Dependencies
# Install dependencies
composer install
# Update dependencies
composer update
CodeIgniter Spark Commands
# List available spark commands
php spark list
# Clear all caches
php spark cache:clear
# Run migrations
php spark migrate
# Rollback migrations
php spark migrate:rollback
Code Style Guidelines
General Principles
- Write clean, readable code without unnecessary comments
- Follow CodeIgniter 4 conventions and PSR-12 PHP standards
- Keep methods focused and under 100 lines when possible
- Avoid deep nesting (max 3-4 levels)
Naming Conventions
| Element | Convention | Examples |
|---|---|---|
| Classes | PascalCase | ProductsModel, BaseController, UsersLogModel |
| Files | Match class name | ProductsModel.php, BaseController.php |
| Methods | camelCase | getProductAlias(), productslog_edit() |
| Variables | camelCase | $productid, $data, $results |
| Properties | snake_case | $table, $primaryKey, $allowedFields |
| Constants | UPPER_SNAKE_CASE | APPPATH, HOMEPATH |
| Namespaces | PascalCase | App\Controllers, App\Models, Config |
File Structure
<?php
namespace App\Controllers;
use App\Models\ProductsModel;
use CodeIgniter\Controller;
class Products extends BaseController
{
protected array $data;
public function index()
{
// method body
}
}
Imports and Namespaces
- Use explicit imports for all external classes
- Namespace should reflect file location (
App\Controllers\*,App\Models\*) - Place namespace at top, followed by imports, then class definition
- Do not use fully qualified class names inline
<?php
namespace App\Controllers;
use App\Models\ProductsModel;
use App\Models\ProductsLogModel;
use CodeIgniter\Controller;
Indentation and Spacing
- Use tabs for indentation (4 spaces per tab is acceptable)
- No trailing whitespace
- One blank line between method definitions
- Space around operators:
$productid = $value; - No space between function name and parentheses:
func()notfunc ()
Arrays and Configuration
// Short array syntax for simple arrays
protected array $data;
$this->data['productowners'] = ['S' => 'Summit', 'C' => 'Customer'];
// Multi-line array with proper alignment
protected $allowedFields = [
'siteid',
'productnumber',
'productname',
'catalogid',
];
Control Structures
// Single-line condition with braces
if ($productid !== null) {
// code
}
// Multi-line conditions
if ($areaid !== '' || $producttypeid !== '') {
$sql .= ' AND ';
}
// Ternary for simple conditions
$locationstartdate = ($this->request->getVar('locationstartdate') === '')
? null
: $this->request->getVar('locationstartdate');
Database Operations
- Use
$db = \Config\Database::connect();for direct queries - Use Query Builder when possible:
$db->table()->get()->getResultArray() - Always escape user input:
$db->escapeString($value) - Use parameterized queries to prevent SQL injection
$builder = $db->table('products');
$builder->where('productid', $productid);
$query = $builder->get();
$results = $query->getResultArray();
Controllers
- All controllers extend
BaseController - Use
$this->request->getMethod()to check request type - Use
$this->request->getVar()or$this->request->getPost()for input - Return views with
return view('view_name', $data); - Validate input with
$this->validate($rules)before processing
public function edit($productid = null)
{
if ($this->request->getMethod() === 'POST') {
$rules = [
'productid' => 'required',
'productnumber' => 'required',
];
if ($this->validate($rules)) {
// process form
}
}
return view('products_edit', $data);
}
Models
- All models extend
CodeIgniter\Model - Define
$table,$primaryKey,$allowedFields - Use
$useSoftDeletesfor soft delete functionality - Define
$useTimestampsif using created_at/updated_at
<?php namespace App\Models;
use CodeIgniter\Model;
class ProductsModel extends Model
{
protected $table = 'products';
protected $primaryKey = 'productid';
protected $allowedFields = ['siteid', 'productnumber', 'productname'];
}
Error Handling
- Use CodeIgniter's built-in validation:
$this->validate($rules) - Return appropriate HTTP status codes in API controllers
- Use
try/catchfor operations that may throw exceptions - Log errors using CodeIgniter's logging:
log_message('error', $message)
try {
$productsModel = new ProductsModel();
$productsModel->update($productid, $data['new_value']);
return view('form_success', $data);
} catch (\Exception $e) {
log_message('error', $e->getMessage());
return view('error_page');
}
Views
- Place views in
app/Views/directory - Use
.phpextension - Access data via associative array:
$products,$data['products'] - Use CodeIgniter's view parser or raw PHP
API Responses
// Return JSON response
return $this->response->setJSON([
'status' => 'success',
'data' => $data,
]);
// Error response
return $this->response->setJSON([
'status' => 'error',
'message' => 'No data found',
]);
Testing
- Extend
CodeIgniter\Test\CIUnitTestCasefor all tests - Test methods must start with
testprefix - Use
@internaldocblock for test classes
<?php
use CodeIgniter\Test\CIUnitTestCase;
final class HealthTest extends CIUnitTestCase
{
public function testIsDefinedAppPath(): void
{
$this->assertTrue(defined('APPPATH'));
}
}
PHP Requirements
- PHP 8.1 or higher
- Extensions required:
intl,mbstring,json - MySQLi database driver by default