Recommended standards

The following coding standards are recommended when working with Appskull. However, it is not required to strictly adhere to these rules; nevertheless, they are highly recommended.

File encoding

Files should be saved using Unicode (UTF-8) encoding.

PHP closing tag

Don't use the PHP closing tag unless it's truly necessary. At the end of a file's content, use a newline character.

File naming

For assets files, use all lowercase letters and use an underscore (_) or a dot (.) as the concatenating character. For all other files, file names should start with a capital letter, and subsequent words should also start with a capital letter. Avoid using any characters to concatenate multiple words.

                        
                            // Assets files
                            main_css_file.css
                            js_file.js
                            bundle.main.js
                            my_photo.jpg

                            // For all other files
                            MyClass.php
                            MyViewFile.php
                            ConfigClass.php
                            LangFile.php
                        
                    

Furthermore, class file names should match the name of the class itself. For example, if you have a class named MyClass, its filename must be MyClass.php.

Class naming

Class names should always start with an uppercase letter. If there are subsequent words, they should also start with a capital letter and should not use any concatenating character when they are concatenated.

Method and variable naming

Method and variable names must use lowerCamelCase.

Space between multiple methods and properties

Use single newline characters to separate them.

Comments

In general, code should be commented prolifically. It not only helps describe the flow and intent of the code for less experienced programmers, but can prove invaluable when returning to your own code months down the line. There is not a required format for comments, but the following are recommended.

For inline comments:

                        
                            // This is a inline comment.
                            # This is also a inline comment.
                        
                    

For multi line comments:

                        
                            /**
                             * This is a
                             * multi line
                             * comment.
                             */
                        
                    

Constants

Constants should always be fully uppercase.

true, false, and null values

true, false, and null values must always be fully lowercase.

Logical operators

Use "||" for "or", "&&" for "and", and use a single space after the "!" operator.

Comparing values

Use strict comparison as much as possible. For example, use "===" and "!==" whenever applicable.

Method typecasting

Always typecast method return types and method header parameters.

Debugging code statements

Do not leave debugging code in your submissions, even when commented out. Things such as var_dump(), print_r() should not be included in your code unless it serves a specific purpose other than debugging.

Whitespace in files

No whitespace can precede the opening PHP tag or follow the closing PHP tag. Output is buffered, so whitespace in your files can cause output to begin before PHP outputs its content, leading to errors and an inability for PHP to send proper headers.

Whitespace

Use spaces for whitespace in your code, not tabs.

Code indentation

Use 4 spaces for indentation.

Class and method body braces

Opening and closing braces should be in same level of indentation.

                        
                            class Hello
                            {

                            }

                            function hello()
                            {

                            }
                        
                    

Conditional statement block braces

Use allman style indenting for opening and closing braces.

                        
                            if () {

                            } else {

                            }
                        
                    

One statement per line

Never combine multiple statements on a single line.

Strings

Always use single quoted strings.

Other recommended standards

  • The app author should update the app_version configuration value in the Main.php configuration file within the app module's Config directory every time there is a change in the app. For example, when updating to a new version of Appskull, adding a brand new module, or making any kind of modification. This helps to purge the browser cache in URLs.

  • When creating class properties to assign custom libraries or configuration classes, it's always recommended to follow this naming convention: moduleName_nameOfClassLibrary, moduleName_nameOfClassConfig. This enhances readability and consistency within the codebase.

                                    
                                        class Users
                                        {
                                            private $app_dataViewLibrary;
    
                                            public function __construct()
                                            {
                                                $this->app_dataViewLibrary = new \Nudasoft\App\Libraries\DataView;
                                            }
                                        }
                                    
                                
  • Don't organize database model files into subdirectories unless there's a complete separation requirement, such as for CRUD operations. This is because database models are often cross-used among user-end and admin-end controllers. Further separation doesn't make sense and introduces unnecessary complexity.

  • For every CRUD operation, create both singular and plural versions of database models. For example, for the Users CRUD, have User.php and Users.php. Use User.php for hosting single user handling methods like addUser and editUser, while use Users.php for hosting bulk dataset/actions related methods like getUsers and deleteUsers. This approach maintains clarity and consistency in your codebase.

  • When creating methods for database models, use HTTP method names such as get, post, put, delete, create, and update for basic CRUD operations. This simplifies the naming convention and aligns with standard HTTP methods, making the code more straightforward and intuitive to work with.

  • Avoid overcomplicating the organization of entities such as controllers, models, config files, and views by creating unnecessary subdirectories like userend or adminend. Instead, place them directly into their respective directories. Only introduce additional directories when a real need for separation arises, such as for a CRUD operation.

    Follow the example below for clarity:

    Example 01: Auth module. Controllers/Signin.php

    Example 02: Users module with sub CRUDs. Controllers/Users.php Controllers/AddUsers.php Controllers/UserRoles/UserRoles.php Controllers/UserRoles/AddUserRole.php

  • Use a single space after the ! operator in conditional statements. For example, (! empty()).

  • Don't use a comma after the last member of an array and use a single space after the each comma. For example: [one, two, three]

  • Helpers, libraries, and model calls should always be placed inside the constructor method and referenced with $this in other places. Avoid calling them directly inside other method bodies. Instead, initialize them within the constructor for better code organization and maintainability.

                                    
                                        class Users
                                        {
                                            private $app_dataViewLibrary;
    
                                            public function __construct()
                                            {
                                                $this->app_dataViewLibrary = new \Nudasoft\App\Libraries\DataView;
                                            }
                                        }
                                    
                                
  • When creating normal view files and template view files, place them in the same level within the Module/Views directory. Only introduce subdirectories like Module/Views/UserRoles when there is a clear need for separation, such as for a CRUD operation. Avoid organizing templates into subdirectories unnecessarily. Simply put layouts, partials, and normal view files in the same level for simplicity and ease of navigation.

  • Avoid postfixing file names of controllers, models, and libraries with their respective type. For instance, instead of using names like SimpleController, MyLibrary, MainConfig, or HelloModel, simply name them as Simple, My, Main, and Hello respectively. There's no need to include the entity type in the file name because their namespace already denotes their entity type when you call these classes.

  • The main config file name in any module should be Main.php.

  • When creating language files for controllers, views, and so on, their filenames should exactly match their corresponding controller, view, and so on. For example, if the controller is named Signin, the language file should also be named Signin.

  • When creating routes, always utilize named routes and follow the naming convention: auth_nameOfRoute, where the auth_ prefix denotes the module name. Incorporate these named routes when redirecting or generating links across your application to facilitate ease of maintenance.

  • When creating email views, use this naming convention: the corresponding controller name followed by the action. For example, Signup + Welcome -> SignupWelcome.php, AddUser + Notify -> AddUserNotify.php.

  • Avoid cross-using different types of language files in different locations. For example, refrain from calling view-related language files inside a controller and vice versa. This separation helps maintain clarity and organization within the codebase.

  • When given the choice between loose and strict comparison operators, opt for the strict comparison. For instance, use 'hello' === 'hello' over loose comparison operators. Strict comparison ensures both value and type match, enhancing code reliability and predictability.

  • Create APIs in a separate application instead of within normal (Non API) modules. Establish a dedicated application solely for delivering APIs and design an API-only module within that application. This approach enhances security since there is no login page for the API-only application. System administrators can manage data through this dedicated application.

  • Use the ! operator to ignore non-important parts first and then continue with the main business logic. This makes reading code from top to bottom much easier. Otherwise, the main logic might get lost in the middle, with less significant return false type stuff appearing at the bottom. This can make the code harder to read and understand.

  • When adding custom validation rules files into a module, create a directory called Validation inside the Module/Config directory, and place those files inside that directory.

  • When creating custom validation rules files, name them like Rules.php. If some rules can be grouped together, then create files like CustomerRules.php.

  • When naming custom validation rules, adhere to this convention: moduleName_ruleName. For instance, auth_userExists, auth_validatePasswordResetCode.

  • When specifying a method's return data type, use the short version of the data type name. For example, use bool instead of boolean, and so on.

  • When setting session values, use the $session->set() and $session->markAsFlashdata() methods. When accessing session values, use the $session->get() and $session->getFlashdata() methods.

  • As a standard practice, use the trim(filter_var($var, FILTER_SANITIZE_FULL_SPECIAL_CHARS)) wrapper for every input from a form submit, even if you know the targeted input doesn't have any special characters. This ensures consistent sanitization of user input and helps prevent potential security vulnerabilities.

  • Module names should always be in plural case, and base routes can be singular, plural, or both. For example, a Users module can have both user and users base routes. However, modules cannot have base routes that do not match the module name. For instance, a Users module cannot have base routes like me or person. It can only have routes like user and users, consistent with its plural name.

  • As a standard practice, it's recommended to declare all variables assigned in the constructor as class properties with appropriate access modifiers in controllers, models, libraries, and other classes. This helps maintain code clarity and organization. Additionally, newer PHP versions like PHP 8.3 may log warning messages if dynamic properties are not declared in the class, so declaring class properties beforehand can help prevent such warnings.

  • As a guideline, add return data types only for class methods. Avoid adding the return type mixed unless PHP 8 is widely adopted. Additionally, refrain from declaring data types for class properties for now, as it may add unnecessary complexity without providing significant value.

  • When using site_url() or base_url(), it's advisable to pass only arrays and avoid using URI segment strings. For example, use site_url(['my', 'example', 'route']) instead of site_url('my/example/route'). This approach enhances readability and maintainability of the code.

  • It's advisable to use regular sessions instead of flash sessions for gates and multi-step forms to ensure smooth navigation and consistent behavior. Flash sessions may lead to issues when users navigate using the back button, potentially causing unexpected form or gate displays. For gates, requests should be invalidated after passing and expire after a configured time for security reasons. In multi-step forms, it's recommended to invalidate all step sessions at once upon completion of the final step, without the need to invalidate sessions between steps. This approach streamlines session management and enhances user experience throughout the process.

  • When creating system settings and user preferences keys, follow these naming conventions. System settings keys should be formatted as [moduleName]_settingKey, for example, app_colorMode. If you are creating a corresponding database-based system setting key, make sure it is exactly the same as the file system-based system setting key. User system preferences keys should follow the format [moduleName]_system_userPreferenceKey, such as app_system_colorMode. User local preferences keys should follow the format [moduleName]_local_userPreferenceKey, like app_local_colorMode.

  • When creating permission keys, adhere to this convention: [moduleName]_[endName(user, my, admin)]_[action(view, add, edit, etc.)]_[location(users, systemSettings, etc.)]. For example: users_admin_view_userPermissions, users_admin_manage_userPermissions.

  • Avoid using justify-content-center for overflow auto/scroll containers, as it can make the top of the scrolling content inaccessible. Instead, utilize margin: auto to center the content. This prevents issues with scrolling to the top of the container. To get more info: https://stackoverflow.com/questions/33454533/cant-scroll-to-top-of-flex-item-that-is-overflowing-container

  • Deemphasize the term Userend. For instance, while using terms like HomeAdminend and HomeMyend, refrain from using HomeUserend. Instead, opt for a simpler term like Home to maintain consistency and clarity.

  • When creating forms and assigning values to the name attribute of inputs, follow the naming convention: moduleName_formName_inputName. For instance, auth_signin_email or users_addUser_firstName.

  • When assigning values to the HTML id attribute, adhere to the convention: this_is_a_id_value. For custom classes, use the convention _this_is_a_class. When naming form name attribute values, follow the convention thisIsANameAttribute. For custom attributes and their values, use the convention _my_custom_attribute="_my_custom_attribute_value".

  • When adding any kind of comments, avoid adding a dot at the end unless it's a paragraph or punctuation has been used before. Use a dot if it's marked as a note. For example, use NOTE: this is a note.

Copyright © Nudasoft.