# Technical documentation — saruefiling

Evidence date: 2026-10-04. Source: `git@bitbucket.org:overdrive/saruefiling.git`, `master` at `9b734e0` (2019-07-03).

Credentials, SMTP passwords, and the login bypass string are described only by where they live. They are not reproduced.

## Stack

| Item | Evidence |
|---|---|
| Language | PHP. Short open tags are required (`README.md`). Server version **Unknown / Requires Confirmation** |
| Framework | Zend Framework 1.11.10, vendored at `library/Zend` (`Zend_Version::VERSION`) |
| Front controller | `public/index.php` builds `Zend_Application` with `APPLICATION_ENV` or `production` |
| Database | `pdo_mysql`. Production section of `application/configs/application.ini` points at a hardcoded IPv4 host and database `teamwizz_SARU`. Staging and testing sections inherit production and do not change the database |
| Timezone | `Africa/Johannesburg` set in `public/index.php` and again in `EpgController` |
| Locale | `resources.locale.default = af_ZA` |
| UI | Server-rendered `.phtml`, jQuery-era admin theme under `public/css`, Font Awesome 4.4.0, FullCalendar assets |
| Spreadsheets | PHPExcel under `public/Classes` |
| PDF | Dompdf under `public/dompdf` |
| Charts | Highcharts assets and a Java exporting server under `public/charts` |
| Mail | `Zend_Mail_Transport_Smtp` |

`composer.json` is not at the repository root. Dompdf ships its own `composer.json`. Vendor trees are committed.

`application/Bootstrap.php` declares an empty `Bootstrap` class. Autoloader namespace `PG_` maps to `library/PG`.

`resources.frontController.Plugins.LayoutPicker` is `PG_Controller_Plugin_LayoutPicker`. The default layout is `default`. A `client` layout name is set under `client.resources.layout.layout` and was not traced further.

## Repository layout

```text
application/          Zend controllers, models, views, layouts, configs
library/              Zend Framework 1, PG plugins, Other
public/               Document root candidate: index.php, css, js, uploads, dompdf, PHPExcel
new/                  Static HTML layout samples, not routed
Footprint_files/      Nested copy of application, library, and public
bitbucket-pipelines.yml
.htaccess             Rewrites into public/
index_repo.html       "blank repo master"
README.md             "php short codes enabled"
```

Not present at `9b734e0`: `appspec.yml`, root `composer.json`, `sonar-project.properties`, `sonarqube_scan.bat`, `public/cron`, PHPUnit config, a test suite.

`application/controllers` has one PHP file per controller. `FixtureController_1.php` and `FirstController_old.php` declare class names that collide with the routed files. Zend maps a URL segment to `{Name}Controller` in `{Name}Controller.php`, so those duplicates are not separate routes.

## Request path

1. Repository `.htaccess`: if the URI does not start with `/public/`, rewrite to `public/{path}`.
2. `public/.htaccess`: if the request is an existing file, symlink, or directory, serve it. Otherwise rewrite to `index.php`.
3. `public/index.php` defines `APPLICATION_PATH`, `UPLOADS_PATH` (`public/uploads`), `IMG_PATH` (`public/IMGS`), and `SYS_PATH` (`public/img/users`). It forces `display_errors` on, sets memory to 800M, sets `max_execution_time` to 0, and runs the application.
4. A commented block at the top of `index.php` would have shown `Background4_2018_maintenance.jpg` and exited. It is not active.

The Apache virtual host document root on the FTP host is **Unknown / Requires Confirmation**. The outer rewrite is useful when the vhost root is the repository root rather than `public/` alone.

## Configuration

`application/configs/application.ini` sections:

| Section | Behaviour |
|---|---|
| `production` | Errors off in the INI, exceptions hidden, MySQL adapter, locale `af_ZA`, layout `default` |
| `staging` | Inherits production with no overrides |
| `testing` | Inherits production, turns `display_errors` on |
| `development` | Inherits production, turns `display_errors` and `displayExceptions` on |

`public/index.php` turns `display_errors` on after the INI is loaded, including when `APPLICATION_ENV` is `production`.

A file `application/configs/Copy of application.ini` duplicates the config. Which file the server reads is the path hardcoded in `index.php`: `application/configs/application.ini`.

## Data

Zend_Db_Table models under `application/models` name the tables. There is no migration directory. Schema shape beyond table names is whatever MySQL already has. Important tables:

| Model | Table | Used for |
|---|---|---|
| `Credentials` | `co_credetials` | Login, `EFLogin`, reset key, scout token |
| `Profile` | `profile` | Person, `UnionType`, `UnionID`, `JobTitle`, `JobType`, `Status`, `Active`, `Role` |
| `Unions` | `ef_unions` | Organisations in the e-filing list |
| `EPG` | `epg` | One form instance: `formdata` JSON, `status`, approval columns |
| `EPGForm` | `epg_forms` | Form definition, `Confidential`, `MembersArray`, `ApproveArray` |
| `EPGHeader` / `EPGSubHeader` / `EPGSections` / `EPGElements` | `EPG_Headers`, `EPG_SubHeaders`, `EPG_Sections`, `EPG_FormElemets` | Template structure |
| `EPGDocumentUpload` | `EPG_FILES` | Files on a form |
| `Grants` / `GrantsRequests` | `grants`, `grantsrequest` | Projects and requests |
| `GirProfile` | `gir_profile` | Dashboard ethnicity counts |
| `EmailSent` | `Email_report` | Template-mail log |
| `EmailTemplate` | `Template_email` | Templates |
| `AccessControl` | `AccessControl` | Settings screen |
| `Squad` | `squad` | Squads and the dashboard counts |

`application/models/DbTable/` also maps a parallel `N_*` table set (`N_Profile`, `N_squad`, `N_Organisation`, and others). Which screens still use the `N_*` models was not fully traced. Provenance: **Implemented** as classes. Usage **Requires Confirmation** screen by screen.

## Auth

Session auth is `Zend_Auth`. The login adapter reads `co_credetials`. The stored identity is the `profile` row, not the credential row. `LastLogin` is updated on the credential row.

Controllers that were read (`IndexController`, `EpgController`, `FirstController`) redirect to `/login/` when there is no identity. `EpgController` skips that check when the action name is `pdf`.

Passwords are MD5. A bypass string in `LoginController` is described in the business rules and is not repeated here.

`AppController` is a separate, session-less entry point for scouting. It checks MD5 and a role flag, then stores `Token`.

## Mail

| Path | Host | From | Logged |
|---|---|---|---|
| `LoginController::sendMailNew` | `mail.sarugby.co.za` port 25 | `accreditation@sarugby.co.za` | No `Email_report` insert in this method |
| `EmailLayout::sendMail` | `mail.footprintapp.net` | `support@saruefiling.com` / `SA Rugby Efiling` | `Email_report` |

Both classes contain the SMTP username and password in source. A commented block in `EmailLayout` names `mail.saruefiling.com` and is not constructed.

## Background work, queues, storage

No queue worker, cron directory, or scheduler is in this revision. `set_time_limit(0)` in `index.php` allows a web request to run without a PHP time limit.

Uploads are addressed by `UPLOADS_PATH` (`public/uploads`). User images use `public/img/users`. Form files go through `EPG_FILES` and the upload action on the form screen. `AppController::scoutAction` writes `q.txt` in the process working directory.

Monitoring is not configured in the repository. Committed files `public/Efiling_Grnd_Error*` (dated 2018-05 through 2019-03) show that PHP error text was written under the web root. Contents were not copied into Silicon Ark.

## Deployment

`bitbucket-pipelines.yml` uses image `python:3.5.7`.

| Branch | Commands |
|---|---|
| `master` | `apt-get` install `zip`, `git`, `git-ftp`, then `git ftp init` with `FTP_USERNAME_LIVE`, `FTP_PASSWORD_LIVE`, `FTP_HOST_LIVE`, path `public_html/saruefiling.overdriveqa.co.za` |
| `development` | Same install, then `git ftp init` with `FTP_*_QA` and the same path string |

`git ftp push` lines are comments. The YAML comment says init is only for the first time. Running init on every pipeline is what the file does today.

There is no AWS CodeDeploy file in this repository.

`pipelineTest` (`67f1721`, message `development push to correct site`) has no step in the YAML.

## Security notes present in the tree

Recorded so the knowledge base matches the code. Not a pentest procedure.

- Database username and password are in `application.ini`.
- SMTP passwords are in `LoginController` and `EmailLayout.php`.
- A login bypass string is in `LoginController`.
- A scout token constant is in `AppController::sendAction`.
- Passwords are MD5.
- Request values are concatenated into SQL.
- `display_errors` is on in the front controller.
- Error logs from 2018–2019 are stored under `public/`.
- `AppController` login does not check `EFLogin`.

## Development and testing

No PHPUnit, no CI test step, and no seed data. `TestController::mailAction` is a mail action, not a test runner. Several `*test*` view scripts (`formtest.phtml`, `projecttest.phtml`, and others) are alternate screens.

The README's only setup instruction is that PHP short codes are enabled.

Local development is expected to use the `development` INI section via `APPLICATION_ENV`. That section still inherits the production database host. Provenance: **Implemented**.

## Library `PG`

`library/PG/Controller/Plugin/EmailLayout.php` builds mail bodies and sends them. `library/PG/Controller/Plugin/html.phtml` is an HTML fragment that welcomes a member to an organisation and tells them to use `www.footprintapp.net`. Placeholders include `[FULLNAME]`, `[ORGNAME]`, `[EMAIL]`, and `[PASSWORD]`.

Provenance: **Implemented** as a template file. Which action still renders it was not confirmed action by action.

## What this document does not establish

- The PHP version on the FTP host.
- Whether `public/` or the repository root is the Apache document root.
- Whether `development` (`8f94d2d`) or `master` (`9b734e0`) was the tree that git-ftp last uploaded.
- Whether `Footprint_files/` is executed.
- Whether `teamwizz_SARU` is shared with the application documented under `silicon_ark/SaruEfiling.com/`.
