Skip to content

Latest commit

 

History

History
172 lines (130 loc) · 10.2 KB

File metadata and controls

172 lines (130 loc) · 10.2 KB

Files & Directories

Naming

Type Naming Convention Example Where Used
Directories lowerCamel case controller, services, viewModels universally
Namespaces lowerCamel Case app\controllers, app\services universally
Files lowerCamel case header.php, navbar.php mostly outside of /app AND in /app/views
Class Files UpperCamel Case User.php, ProjectCtrl.php /app
Non-code files kebab-case (hyphen) logo-FFF.svg, db-access.png images, media, assets

Abbreviations

Because filenames can get very long. the following abbreviations are used:

Full Name Abbreviation Naming Example
Model - Suffix UserModel.php
Dto - Suffix UserIdentityDto.php
View - Suffix landingPage.php / login
ViewModel VM Suffix UserVM.php
Controller Ctrl Suffix UserCtrl.php
Service Serv Suffix UserServ.php
Repository Repo Suffix UserRepo.php
Exception Exc Suffix UserServExc.php / UserRepoExc.php
Interface I Prefix IUserServ.php / IUserRepo.php

Code

Exception handling

Layer Throws Catches Error Messages
Repository *BaseRepoExc (impl.) PDOException (logs, throws RepoExc (impl.)) Technical for developers (Not reachable for end-users)
Service *BaseServExc (impl.) Via ServExc::handleRepoCall() User-friendly for display
Controller - ServExc (impl.) & Exception as fallback Sets flash messages & redirects to Correct OR Exception specific path

NOTE: Impl. = Implementation (concrete class, not interface/abstract)

Method naming

Methods follow: <action><cardinality><property>By<criteria> (e.g., IUserServ::getByEmail, IUserServ::getUserIdentityById)

  • Cardinality should only be used when performing an action on many/more instead of one, e.g., IDanceArtistServ::getManyByShowId or IYummyReservationServ::getManyByRestaurantId
  • Property is optional if the action is clear without it, e.g., IUserRepo::getById NOT IUserRepo::getUserById
Layer Action Examples
Repository CRUD: create*, get*, exists*,
update*, remove*, delete*
fetchByEmail, existsByUsername, getUserIdentityById
Service Same as repository, but less strict (not requiring 'By') verifyAccessRole, editAccount, login
Controller <pageName>+Page (GET) OR <action> (POST/PUT/DELETE) loginPage (GET), login (POST), editAccount (POST)

Style & Formatting

Pattern Rule Example
Single-line conditions Omit braces for single statements (implied body) if ($condition)
throw new Exception();
Nested conditions Always use braces for clarity (explicit body) if ($outer) {
if ($nested) { ... }
}
Multi-line arrays [ on the var line, ] on it's own line $array = [
'key' => 'value'
];
SQL queries Same logic as multi-line rule $stmt->execute([
'key' => $value
]);
  • Indentation: 4 spaces

Comments & TODO

Type Usage Example
PHPDoc (classes) Brief description /** Toast notification component for rendering flash messages */
PHPDoc (methods) Description + @param + @return + @throws /** Returns a user by its ID.
* @throws UserRepoExc */
Inline comments Explain non-obvious logic or decisions // Temp placeholder value, will be replaced by the service
Section headers Group related code with //region comments //region POST Requests ... //endregion
TODO (general) Task without specific assignee // TODO: Add exceptions
TODO (assigned) Task assigned to specific person // TODO (Stef): Refactor this method to use exceptions

PHPDoc tags: Use @param, @return, @throws for interfaces and public methods (implementation methods do not)
Inline comments: Place above the code block, not on the same line (unless very short)


AI

  • Priority (Suggestion): Your brain → Official docs / Forums → Popular Composer/NPM dependencies → AI assistance
  • When using AI: Every generated line must be understood, analyzed, and verified for adherence to this style guide
  • Preferred AI: Use agentic AI (such as CoPilot) over copy-paste LLM conversations (due to agentic AI having better project context & file awareness)
  • Repetition: Repetitive tasks can be done with AI (as long as no new concept needs to be introduced), but must be reviewed for consistency and correctness
  • Documentation: Agentic autofill AI (such as CoPilot) can be used and is recommended for use in generating documentation (PHPDoc, comments). As long as the generated text is verified for accuracy and clarity

Tailwind

Custom component naming

File Description Example
^fest-.*$ Global components / festival specific components fest-header, fest-modal, fest-wysiwyg
^dance-.*$ Dance specific components dance-artist-card, dance-list
^history-.*$ History specific components history-timeline, history-location
^jazz-.*$ Jazz specific components jazz-artist-card, jazz-list
^yummy-.*$ Yummy specific components yummy-card, yummy-list

Component creation guidelines

Because tailwind is easily added as classes, these predefined components are only necessary for frequently used combinations of tailwind classes. Such as: fest-header, dance-artist-card & yummy-restaurant-card

Don't create new components just for a better name. Instead, use the base component and customize it with Tailwind classes. For example, use fest-header bg-red-500 instead of creating a separate dance-header component. This prevents component bloat and keeps your styling flexible. Only if your variant is used frequently AND having a significant amount of additions, should you create a new component with a new name.

When you need size or structural variants (not just color/spacing tweaks), follow Tailwind's naming convention with suffixes like fest-container-sm or dance-container-lg.

Consider using custom components instead of making them 'shared' with fest- if you think you might change the tailwind of that component in the future. As this results in other developers having to change their tailwind classes as well, which can be easily forgotten and cause bugs in their components/views.

Custom colors

Custom colors can also be specified in input @theme. If your colorscheme is too familiar to tailwind's default palette, then just use that.

Sources

PHP & JS

TailwindCSS

Media