Skip to main content

Overview

Sistema Magdaleno follows the CakePHP 1.3 MVC (Model-View-Controller) architecture pattern. The application is organized into distinct layers that separate business logic, data access, and presentation concerns.

Directory Structure

sistema_magdaleno/
├── app/
│   ├── config/              # Configuration files
│   ├── controllers/         # Controller classes
│   │   ├── components/     # Reusable controller logic
│   │   └── *_controller.php
│   ├── models/             # Model classes
│   │   ├── behaviors/      # Reusable model logic
│   │   └── datasources/    # Custom data sources
│   ├── views/              # View templates
│   │   ├── elements/       # Reusable view fragments
│   │   ├── helpers/        # View helper classes
│   │   ├── layouts/        # Page layouts
│   │   └── {controller}/   # Controller-specific views
│   ├── webroot/            # Publicly accessible files
│   │   ├── css/
│   │   ├── js/
│   │   ├── img/
│   │   └── files/          # Uploaded files
│   ├── tmp/                # Temporary files & cache
│   ├── vendors/            # Third-party libraries
│   ├── plugins/            # CakePHP plugins
│   ├── locale/             # Internationalization files
│   ├── tests/              # Unit tests
│   ├── app_controller.php  # Base controller
│   └── index.php           # Application entry point
├── cake/                   # CakePHP core framework
├── plugins/                # Global plugins
├── vendors/                # Global vendor libraries
└── index.php               # Root entry point

Controllers

Location

app/controllers/

Available Controllers

ControllerPurpose
denuncias_controller.phpComplaint/report management
galleries_controller.phpImage gallery CRUD operations
groups_controller.phpUser group & permission management
locales_controller.phpBusiness location management
pages_controller.phpStatic page handling
promos_controller.phpPromotional content management
registers_controller.phpUser registration & campaigns
users_controller.phpUser authentication & profile management
ventas_controller.phpSales/transaction handling
videos_controller.phpVideo content management

Base Controller (AppController)

File: app/app_controller.php All controllers extend AppController, which provides shared functionality:
class AppController extends Controller {
    var $components = array(
        'Acl',           // Access Control Lists
        'Auth',          // Authentication
        'Session',       // Session management
        'Email',         // Email sending
        'PasswordHelper' // Password utilities
    );
}

Key Methods

beforeFilter() Executes before every controller action:
function beforeFilter() {
    parent::beforeFilter();
    
    // Configure authentication
    $this->Auth->loginAction = array(
        'controller' => 'users', 
        'action' => 'login'
    );
    
    // Allow public access to specific actions
    $this->Auth->allow('add_vendedor', 'consulta_codigo', 'registrado', 'display');
    
    // Set redirect after login
    $this->Auth->loginRedirect = array(
        'controller' => 'users', 
        'action' => 'home'
    );
    
    // Enable controller-based authorization
    $this->Auth->authorize = 'controller';
}
isAuthorized() Authorization callback (returns true to allow access):
function isAuthorized() {
    return true; // Delegates to ACL system
}
build_acl() Automatically builds ACL tree from controllers/actions (debug mode only):
  • Scans all controllers in app/controllers/
  • Creates ACO nodes for each controller
  • Creates ACO nodes for each public action
  • Supports plugin controllers

Controller Naming Convention

  • File: {plural_name}_controller.php (e.g., users_controller.php)
  • Class: {PluralName}Controller (e.g., UsersController)
  • Extends: AppController
class GalleriesController extends AppController {
    var $name = 'Galleries';
    // ...
}

Models

Location

app/models/

Available Models

ModelDatabase TablePurpose
UserusersUser accounts
GroupgroupsUser groups
GallerygalleriesImage galleries
ArchivoarchivosUploaded files
VideovideosVideo content
CategorycategoriesContent categories
Locale(locales table)Business locations
CampanacampanasMarketing campaigns
RegisterregistersUser registrations
Denuncia(denuncias table)Complaints/reports
AcoacosACL objects
AroarosACL requesters
ArosAcoaros_acosACL permissions junction

Model Naming Convention

  • File: {singular_name}.php (e.g., user.php)
  • Class: {SingularName} (e.g., User)
  • Extends: AppModel
  • Table: {plural_name} (e.g., users)
class Gallery extends AppModel {
    var $name = 'Gallery';
    var $primaryKey = 'id_galeria'; // Custom PK
}

Model Associations

belongsTo

var $belongsTo = array(
    'User' => array(
        'className' => 'User',
        'foreignKey' => 'usuario_id_usuario'
    )
);

hasMany

var $hasMany = array(
    'Gallery' => array(
        'className' => 'Gallery',
        'foreignKey' => 'usuario_id_usuario'
    )
);

hasAndBelongsToMany (HABTM)

var $hasAndBelongsToMany = array(
    'Archivo' => array(
        'className' => 'Archivo',
        'joinTable' => 'archivos_galleries',
        'foreignKey' => 'galerias_id_galeria',
        'associationForeignKey' => 'files_id_file'
    )
);

Model Behaviors

Tree Behavior (for nested data):
var $actsAs = array('Tree');
ACL Behavior (for authentication):
var $actsAs = array('Acl' => array('requester'));

Validation

Models define validation rules:
var $validate = array(
    'username' => array(
        'rule1' => array(
            'rule' => array('minLength', 4),
            'message' => 'Minimum 4 characters required'
        ),
        'rule2' => array(
            'rule' => array('notEmpty'),
            'message' => '* Required'
        )
    )
);

Views

Location

app/views/

View Structure

views/
├── layouts/
│   └── default.ctp          # Main layout wrapper
├── elements/
│   ├── header.ctp           # Reusable header
│   └── footer.ctp           # Reusable footer
├── helpers/
│   └── custom_helper.php    # View helper classes
├── users/
│   ├── index.ctp           # Users list
│   ├── login.ctp           # Login form
│   ├── add.ctp             # Add user form
│   └── edit.ctp            # Edit user form
└── galleries/
    ├── index.ctp           # Galleries list
    ├── view.ctp            # Single gallery view
    ├── add.ctp             # Add gallery form
    └── edit.ctp            # Edit gallery form

View Naming Convention

  • File: {action_name}.ctp (e.g., index.ctp, add.ctp)
  • Location: views/{controller}/{action}.ctp

Automatic View Rendering

CakePHP automatically renders views based on controller/action:
// Controller: GalleriesController
// Action: index()
// View: app/views/galleries/index.ctp

CakePHP Conventions

File Naming

TypeConventionExample
Controller{plural}_controller.phpusers_controller.php
Model{singular}.phpuser.php
View{action}.ctpindex.ctp
Helper{name}_helper.phpform_helper.php
Component{name}_component.phpauth_component.php
Behavior{name}_behavior.phptree_behavior.php

Class Naming

TypeConventionExample
Controller{PluralName}ControllerUsersController
Model{SingularName}User
Helper{Name}HelperFormHelper
Component{Name}ComponentAuthComponent
Behavior{Name}BehaviorTreeBehavior

Database Conventions

ItemConventionExample
Table{plural}_nameusers, galleries
Primary Keyid or {singular}_idid_usuario
Foreign Key{singular}_id{field}usuario_id_usuario
Junction Table{table1}_{table2}archivos_galleries

URL Routing

CakePHP follows convention-based routing:
/{controller}/{action}/{param1}/{param2}

Examples:
/users/login
/galleries/view/123
/videos/edit/45

Components

Location: app/controllers/components/ Reusable controller logic shared across multiple controllers.

Built-in Components Used

  • Auth: User authentication and authorization
  • Acl: Access Control List management
  • Session: Session data management
  • Email: Email sending functionality
  • PasswordHelper: Custom password utilities

Configuration

Key Configuration Files

  • app/config/core.php - Core application settings
  • app/config/database.php - Database connection settings
  • app/config/routes.php - Custom URL routing rules
  • app/config/bootstrap.php - Application bootstrap code

Application Flow

┌─────────────────────────────────────────────────┐
│  1. Request: /galleries/view/123               │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  2. Router parses URL                           │
│     Controller: Galleries                       │
│     Action: view                                │
│     Params: [123]                               │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  3. AppController::beforeFilter()               │
│     - Initialize Auth component                 │
│     - Check ACL permissions                     │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  4. GalleriesController::view(123)              │
│     - Query Gallery model                       │
│     - Set view variables                        │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  5. Gallery->find('first', ['id' => 123])       │
│     - Execute SQL query                         │
│     - Return data array                         │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  6. Render: views/galleries/view.ctp            │
│     Layout: views/layouts/default.ctp           │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  7. Response: HTML output to browser            │
└─────────────────────────────────────────────────┘

Best Practices

Controller Best Practices

  1. Keep controllers thin - Business logic belongs in models
  2. Use beforeFilter() for shared setup logic
  3. Redirect after POST - Prevent form resubmission
  4. Set proper flash messages - Inform users of results

Model Best Practices

  1. Define all associations - Enable automatic data fetching
  2. Use validation rules - Ensure data integrity
  3. Add custom find methods - Encapsulate complex queries
  4. Use behaviors - Share logic across models

View Best Practices

  1. Use elements - Reuse common view fragments
  2. Use helpers - Keep views clean of complex logic
  3. Separate layouts - Different designs for different sections
  4. Escape output - Prevent XSS attacks with h()

Build docs developers (and LLMs) love