From 44a0bedaf36c1ca63aff3b3466143857861f1a51 Mon Sep 17 00:00:00 2001 From: Andrii Riabchenko Date: Sun, 11 May 2025 15:30:19 +0300 Subject: [PATCH 1/5] Refactor meta handling across controllers and views; remove unused keywords and welcome component --- app/controller/catalog/components.php | 5 +- app/controller/catalog/csrf_protection.php | 5 +- app/controller/catalog/pagination.php | 5 +- app/controller/common/header.php | 8 +-- app/controller/common/welcome.php | 9 --- app/controller/error/not_found.php | 5 +- app/controller/index.php | 7 ++- app/language/en/catalog/components.php | 1 - app/language/en/catalog/csrf_protection.php | 1 - app/language/en/catalog/pagination.php | 1 - app/language/en/error/not_found.php | 1 - app/view/common/header.twig | 17 +---- app/view/common/welcome.twig | 22 ------- app/view/index.twig | 23 ++++++- composer.json | 3 +- composer.lock | 70 +++++++++++++++++++-- core/bootstrap.php | 1 + core/library/meta.php | 68 ++++++++++++++++++++ migrate.php | 17 ++++- 19 files changed, 187 insertions(+), 82 deletions(-) delete mode 100644 app/controller/common/welcome.php delete mode 100644 app/view/common/welcome.twig create mode 100644 core/library/meta.php diff --git a/app/controller/catalog/components.php b/app/controller/catalog/components.php index df0c854..8a0fd1f 100644 --- a/app/controller/catalog/components.php +++ b/app/controller/catalog/components.php @@ -4,9 +4,8 @@ class ControllerCatalogComponents extends Controller { public function index() { $this->app->useLanguage('catalog/components'); - $this->response->setTitle($this->language->get('meta_title')); - $this->response->setDescription($this->language->get('meta_description')); - $this->response->setKeywords($this->language->get('meta_keywords')); + $this->meta->setTitle($this->language->get('meta_title')); + $this->meta->setDescription($this->language->get('meta_description')); $this->response->addStyle('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css'); $this->response->addScript('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js'); diff --git a/app/controller/catalog/csrf_protection.php b/app/controller/catalog/csrf_protection.php index d4982cf..f460f3e 100644 --- a/app/controller/catalog/csrf_protection.php +++ b/app/controller/catalog/csrf_protection.php @@ -6,9 +6,8 @@ class ControllerCatalogCsrfProtection extends Controller { public function index() { $this->app->useLanguage('catalog/csrf_protection'); - $this->response->setTitle($this->language->get('meta_title')); - $this->response->setDescription($this->language->get('meta_description')); - $this->response->setKeywords($this->language->get('meta_keywords')); + $this->meta->setTitle($this->language->get('meta_title')); + $this->meta->setDescription($this->language->get('meta_description')); $this->data['action'] = $this->url->link('catalog/csrf_protection'); diff --git a/app/controller/catalog/pagination.php b/app/controller/catalog/pagination.php index c99bb0f..bcd4686 100644 --- a/app/controller/catalog/pagination.php +++ b/app/controller/catalog/pagination.php @@ -5,9 +5,8 @@ public function index() { $this->app->useLanguage('catalog/pagination'); $this->app->useModel('demo/demo'); - $this->response->setTitle($this->language->get('meta_title')); - $this->response->setDescription($this->language->get('meta_description')); - $this->response->setKeywords($this->language->get('meta_keywords')); + $this->meta->setTitle($this->language->get('meta_title')); + $this->meta->setDescription($this->language->get('meta_description')); $page = isset($this->request->get['page']) ? $this->request->get['page'] : 1; diff --git a/app/controller/common/header.php b/app/controller/common/header.php index 224150b..3e7c39f 100644 --- a/app/controller/common/header.php +++ b/app/controller/common/header.php @@ -2,12 +2,8 @@ class ControllerCommonHeader extends Controller { public function index() { - $this->data['title'] = $this->response->getTitle(); - $this->data['description'] = $this->response->getDescription(); - $this->data['keywords'] = $this->response->getKeywords(); - $this->data['robots'] = $this->response->getRobots(); - $this->data['canonical'] = $this->response->getCanonical(); - $this->data['links'] = $this->response->getLinks(); + $this->data['meta'] = $this->meta->getMetaTags(); + $this->data['styles'] = $this->response->getStyles(); $scripts = $this->response->getScripts(); diff --git a/app/controller/common/welcome.php b/app/controller/common/welcome.php deleted file mode 100644 index 8d35b05..0000000 --- a/app/controller/common/welcome.php +++ /dev/null @@ -1,9 +0,0 @@ -data['cover'] = $this->staticfile->getUri('img/welcome.png'); - - return $this->view->template('common/welcome', $this->data); - } -} diff --git a/app/controller/error/not_found.php b/app/controller/error/not_found.php index 3f7ec05..e9ad023 100644 --- a/app/controller/error/not_found.php +++ b/app/controller/error/not_found.php @@ -4,9 +4,8 @@ class ControllerErrorNotFound extends Controller { public function index() { $this->app->useLanguage('error/not_found'); - $this->response->setTitle($this->language->get('meta_title')); - $this->response->setDescription($this->language->get('meta_description')); - $this->response->setKeywords($this->language->get('meta_keywords')); + $this->meta->setTitle($this->language->get('meta_title')); + $this->meta->setDescription($this->language->get('meta_description')); $this->data['heading_title'] = $this->language->get('heading_title'); diff --git a/app/controller/index.php b/app/controller/index.php index 8ec0c01..8695bc1 100644 --- a/app/controller/index.php +++ b/app/controller/index.php @@ -2,12 +2,13 @@ class ControllerIndex extends Controller { public function index() { - $this->response->setTitle($this->language->get('meta_title')); - $this->response->setDescription($this->language->get('meta_description')); - $this->response->setKeywords($this->language->get('meta_keywords')); + $this->meta->setTitle($this->language->get('meta_title')); + $this->meta->setDescription($this->language->get('meta_description')); $this->data['heading_title'] = $this->language->get('heading_title'); + $this->data['cover'] = $this->staticfile->getUri('img/welcome.png'); + $this->data['header'] = $this->load->controller('common/header'); $this->data['welcome'] = $this->load->controller('common/welcome'); diff --git a/app/language/en/catalog/components.php b/app/language/en/catalog/components.php index 4f9c33d..5173dbe 100644 --- a/app/language/en/catalog/components.php +++ b/app/language/en/catalog/components.php @@ -3,7 +3,6 @@ return [ 'meta_title' => 'PHPapp :: Components', 'meta_description' => 'This is a simple components page.', - 'meta_keywords' => 'hello, world', 'heading_title' => 'Components', 'text_help' => 'This page displays all the classes and libraries in the core directory.', 'text_classes' => 'Classes', diff --git a/app/language/en/catalog/csrf_protection.php b/app/language/en/catalog/csrf_protection.php index a797bcd..4c1e059 100644 --- a/app/language/en/catalog/csrf_protection.php +++ b/app/language/en/catalog/csrf_protection.php @@ -4,7 +4,6 @@ 'heading_title' => 'CSRF Protection', 'meta_title' => 'CSRF Protection', 'meta_description' => 'CSRF Protection', - 'meta_keywords' => 'CSRF Protection', 'text_form' => 'Form', 'entry_email' => 'Email', 'entry_password' => 'Password', diff --git a/app/language/en/catalog/pagination.php b/app/language/en/catalog/pagination.php index 04af958..3f8417f 100644 --- a/app/language/en/catalog/pagination.php +++ b/app/language/en/catalog/pagination.php @@ -3,7 +3,6 @@ return [ 'meta_title' => 'PHPapp :: Pagination', 'meta_description' => 'This is a simple pagination page.', - 'meta_keywords' => 'hello, world', 'heading_title' => 'Pagination Example', 'column_post_id' => 'ID', 'column_hash' => 'Hash', diff --git a/app/language/en/error/not_found.php b/app/language/en/error/not_found.php index e6456d9..4388c63 100644 --- a/app/language/en/error/not_found.php +++ b/app/language/en/error/not_found.php @@ -3,6 +3,5 @@ return [ 'meta_title' => 'PHPapp :: Error', 'meta_description' => 'This is a simple error page.', - 'meta_keywords' => 'hello, world', 'heading_title' => 'Error 404', ]; \ No newline at end of file diff --git a/app/view/common/header.twig b/app/view/common/header.twig index 9add195..aeb3b1b 100644 --- a/app/view/common/header.twig +++ b/app/view/common/header.twig @@ -3,22 +3,7 @@ - {{ title }} - {% if description %} - - {% endif %} - {% if keywords %} - - {% endif %} - {% if robots %} - - {% endif %} - {% if canonical %} - - {% endif %} - {% for link in links %} - - {% endfor %} + {{ meta }} {% for style in styles %} {% endfor %} diff --git a/app/view/common/welcome.twig b/app/view/common/welcome.twig deleted file mode 100644 index b443dc1..0000000 --- a/app/view/common/welcome.twig +++ /dev/null @@ -1,22 +0,0 @@ -
-
-
-
- Welcome to the PHP App -
-
-

Welcome to the PHP App

-

This is a simple PHP application that uses the MVC pattern. It is a starting point for building a PHP application from scratch.

-

What is MVC?

-

MVC stands for Model-View-Controller. It is a design pattern that separates the application into three main components: the model, the view, and the controller.

-

What is this application using?

-

This application is using the following technologies:

-
    -
  • PHP
  • -
  • Twig
  • -
  • Bootstrap
  • -
  • jQuery
  • -
-
-
-
\ No newline at end of file diff --git a/app/view/index.twig b/app/view/index.twig index 6f530de..e1f25ac 100644 --- a/app/view/index.twig +++ b/app/view/index.twig @@ -1,3 +1,24 @@ {{ header }} -{{ welcome }} +
+
+
+
+ Welcome to the PHP App +
+
+

Welcome to the PHP App

+

This is a simple PHP application that uses the MVC pattern. It is a starting point for building a PHP application from scratch.

+

What is MVC?

+

MVC stands for Model-View-Controller. It is a design pattern that separates the application into three main components: the model, the view, and the controller.

+

What is this application using?

+

This application is using the following technologies:

+
    +
  • PHP
  • +
  • Twig
  • +
  • Bootstrap
  • +
  • jQuery
  • +
+
+
+
{{ footer }} \ No newline at end of file diff --git a/composer.json b/composer.json index 5b56540..6eb48ef 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,8 @@ "twig/twig": "^3.9", "vlucas/phpdotenv": "^5.6", "google/apiclient": "^2.0", - "monolog/monolog": "^3.9" + "monolog/monolog": "^3.9", + "melbahja/seo": "^2.1" }, "config": { "vendor-dir": "core/vendor" diff --git a/composer.lock b/composer.lock index 1632b1f..6312e1b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "60ec694ca36984f88a96737c757f01cd", + "content-hash": "464e241eb048d05ad3e25ae360cecb44", "packages": [ { "name": "firebase/php-jwt", @@ -630,6 +630,66 @@ ], "time": "2024-07-18T11:15:46+00:00" }, + { + "name": "melbahja/seo", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/melbahja/seo.git", + "reference": "22b0b3273bf9c8867cadf018e4daa3e426525929" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/melbahja/seo/zipball/22b0b3273bf9c8867cadf018e4daa3e426525929", + "reference": "22b0b3273bf9c8867cadf018e4daa3e426525929", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-xml": "*", + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Melbahja\\Seo\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mohamed ELbahja", + "email": "mohamed@elbahja.me", + "homepage": "https://elbahja.me", + "role": "Developer" + } + ], + "description": "Simple PHP library to help developers 🍻 do better on-page SEO optimization", + "keywords": [ + "PHP7", + "meta tags", + "open graph", + "schema.org", + "search engine optimization", + "seo", + "sitemap index", + "sitemap.xml", + "sitemaps", + "twitter tags" + ], + "support": { + "issues": "https://github.com/melbahja/seo/issues", + "source": "https://github.com/melbahja/seo/tree/v2.1.1" + }, + "time": "2022-09-11T11:16:07+00:00" + }, { "name": "monolog/monolog", "version": "3.9.0", @@ -1888,10 +1948,10 @@ "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/core/bootstrap.php b/core/bootstrap.php index cefccf6..ad661e0 100644 --- a/core/bootstrap.php +++ b/core/bootstrap.php @@ -33,6 +33,7 @@ $registry->set('session', new Session($registry)); $registry->set('pagination', new Pagination()); $registry->set('google_auth', new google_auth($registry)); +$registry->set('meta', new Meta()); $registry->set('view', new View($registry)); diff --git a/core/library/meta.php b/core/library/meta.php new file mode 100644 index 0000000..48b9603 --- /dev/null +++ b/core/library/meta.php @@ -0,0 +1,68 @@ +title = $title; + } + + public function setDescription($description) { + $this->description = $description; + } + + public function setMeta($property, $value) { + $this->meta[$property] = $value; + } + + public function setImage($image) { + $this->image = $image; + } + + public function setCanonical($canonical) { + $this->canonical = $canonical; + } + + public function setRobots($robots) { + $this->robots = $robots; + } + + public function getMetaTags() { + $metaTags = new MetaTags(); + + if ($this->title) { + $metaTags->title($this->title); + } + + if ($this->description) { + $metaTags->description($this->description); + } + + if ($this->meta) { + foreach ($this->meta as $property => $value) { + $metaTags->meta($property, $value); + } + } + + if ($this->image) { + $metaTags->image($this->image); + } + + if ($this->canonical) { + $metaTags->canonical($this->canonical); + } + + if ($this->robots) { + $metaTags->robots($this->robots); + } + + return $metaTags; + } +} \ No newline at end of file diff --git a/migrate.php b/migrate.php index 8bf7dbc..29adbe9 100644 --- a/migrate.php +++ b/migrate.php @@ -1,8 +1,19 @@ set('env', new Env()); + +$db = new Db($registry); $command = $argv[1] ?? null; @@ -57,7 +68,7 @@ function migrate($db) { function rollback($db) { echo "Rolling back last migration...\n"; - $lastMigration = $db->query("SELECT migration FROM migrations ORDER BY id DESC LIMIT 1")[0]['migration'] ?? null; + $lastMigration = $db->query("SELECT migration FROM migrations ORDER BY id DESC LIMIT 1", true)[0]['migration'] ?? null; if ($lastMigration) { require_once __DIR__ . "/migrations/$lastMigration.php"; From 9a7dabc0a9ba21dc346548867c03380b01ffcf10 Mon Sep 17 00:00:00 2001 From: Andrii Riabchenko Date: Sun, 11 May 2025 15:34:20 +0300 Subject: [PATCH 2/5] Add database port and prefix fields to installer; enhance exec function checks --- www/installer.php | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/www/installer.php b/www/installer.php index c0f99f3..6eb0f75 100644 --- a/www/installer.php +++ b/www/installer.php @@ -5,6 +5,8 @@ $dbName = $_POST['db_name'] ?? 'database'; $dbUser = $_POST['db_user'] ?? 'root'; $dbPassword = $_POST['db_password'] ?? ''; + $dbPort = $_POST['db_port'] ?? '3306'; + $dbPrefix = $_POST['db_prefix'] ?? 'prefix_'; // Get form data for web config $useSSL = isset($_POST['use_ssl']) ? true : false; @@ -12,7 +14,7 @@ $defaultLanguage = $_POST['default_language'] ?? 'en'; // Generate .env file - $envContent = "DB_HOST=\"$dbHost\"\nDB_NAME=\"$dbName\"\nDB_USER=\"$dbUser\"\nDB_PASS=\"$dbPassword\"\n"; + $envContent = "DB_HOST=\"$dbHost\"\nDB_NAME=\"$dbName\"\nDB_USER=\"$dbUser\"\nDB_PASS=\"$dbPassword\"\nDB_PORT=\"$dbPort\"\nDB_PREFIX=\"$dbPrefix\"\n"; file_put_contents(__DIR__ . '/../.env', $envContent); // Generate web.php config @@ -27,6 +29,24 @@ // Check if composer.phar exists if (!file_exists(__DIR__ . '/../composer.phar')) { + // Check if exec is available + if (!function_exists('exec') || in_array('exec', array_map('trim', explode(',', ini_get('disable_functions'))))) { + echo '
+ Warning: The exec function is disabled on this server. + Please manually install Composer and dependencies by running these commands in your terminal: +
+cd ' . dirname(__DIR__) . '
+php -r "copy(\'https://getcomposer.org/installer\', \'composer-setup.php\');"
+php composer-setup.php
+php -r "unlink(\'composer-setup.php\');"
+php composer.phar install
+php migrate.php migrate
+                
+ Then reload this page after completing these steps. +
'; + exit; + } + // Download composer.phar file_put_contents('composer-setup.php', file_get_contents('https://getcomposer.org/installer')); exec('php composer-setup.php', $output, $returnVar); @@ -36,6 +56,21 @@ } } + // Check if exec is available before continuing with other commands + if (!function_exists('exec') || in_array('exec', array_map('trim', explode(',', ini_get('disable_functions'))))) { + echo '
+ Warning: The exec function is disabled on this server. + Please manually complete the installation by running these commands in your terminal: +
+cd ' . dirname(__DIR__) . '
+php composer.phar install
+php migrate.php migrate
+            
+ Then reload this page after completing these steps. +
'; + exit; + } + // Run composer install exec('php ' . __DIR__ . '/../composer.phar install', $output, $returnVar); if ($returnVar !== 0) { @@ -82,6 +117,14 @@ +
+ + +
+
+ + +

Web Configuration

From e57984e8d3f258eb633efac791c14c7bfd2b4a9d Mon Sep 17 00:00:00 2001 From: Andrii Riabchenko Date: Sun, 11 May 2025 15:36:44 +0300 Subject: [PATCH 3/5] Add nginx configuration file for PHP application setup --- nginx.conf.example | 24 ++++++++++++++++++++++++ phpapp-server | 41 ----------------------------------------- 2 files changed, 24 insertions(+), 41 deletions(-) create mode 100644 nginx.conf.example delete mode 100755 phpapp-server diff --git a/nginx.conf.example b/nginx.conf.example new file mode 100644 index 0000000..0d7ce56 --- /dev/null +++ b/nginx.conf.example @@ -0,0 +1,24 @@ +server { + listen 80; + server_name example.com; + root /path/to/phpapp/www; + index index.php; + + # Rewrite rules similar to .htaccess + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # Handle PHP files + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; # Adjust to your PHP-FPM version + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + # Deny access to hidden files + location ~ /\. { + deny all; + } +} \ No newline at end of file diff --git a/phpapp-server b/phpapp-server deleted file mode 100755 index 1c9ec21..0000000 --- a/phpapp-server +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env sh -eo pipefail - -set -e - -IP=127.0.0.1 -PORT=8080 - -function stop_server { - if [ -f server.pid ]; then - kill $(cat server.pid) - rm server.pid - fi -} - -function start_server { - php -S $IP:$PORT -t ./www & - echo $! > server.pid -} - -function status_server { - if [ -f server.pid ]; then - echo "Server is running" - else - echo "Server is not running" - fi -} - -case $1 in - --start) - start_server - ;; - --stop) - stop_server - ;; - --status) - status_server - ;; - *) - echo "Invalid command" - ;; -esac \ No newline at end of file From 86f993352f950be577c4350ebc1ee3e07b2d75a0 Mon Sep 17 00:00:00 2001 From: Andrii Riabchenko Date: Sun, 11 May 2025 15:41:00 +0300 Subject: [PATCH 4/5] Add meta.php for SEO management and update README with new features --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5be5d5c..f4cca87 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,14 @@ - **staticfile.php**: Serves static files (CSS, JS, images). - **url.php**: Generates URLs and manages routing. - **log.php**: Provides centralized logging functionality using Monolog. +- **meta.php**: Manages SEO metadata including page titles, descriptions, Open Graph tags, and robots directives using the Melbahja/Seo package. ### New Features - **Migration System:** Manage database schema changes with ease. Use `php migrate.php migrate` to apply migrations, `php migrate.php rollback` to undo the last migration, and `php migrate.php status` to check migration status. - **Interactive Installer:** Quickly set up your application by providing database and web configuration details in a user-friendly web installer. - **Centralized Logging:** Monitor application events, errors, and debugging information using the integrated Monolog-based logging system. +- **SEO Management:** Easily manage page metadata, title tags, Open Graph properties, and other SEO essentials using the integrated meta.php library powered by Melbahja/Seo package. ## License From 049e2c80549957a350012eb43a911c95158ae15a Mon Sep 17 00:00:00 2001 From: Andrii Riabchenko Date: Sun, 11 May 2025 15:50:23 +0300 Subject: [PATCH 5/5] Add CODE_OF_CONDUCT.md and CONTRIBUTING.md for community guidelines and contribution best practices --- CODE_OF_CONDUCT.md | 89 +++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 113 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..679e49e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,89 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +--- + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or email address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +--- + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +--- + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +--- + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [ryabchenko.andrew@gmail.com](mailto:ryabchenko.andrew@gmail.com). All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +--- + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +--- + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html). + +Community Impact Guidelines were inspired by [Mozilla’s code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are available at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..71eb081 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,113 @@ +# Contributing to PHPapp + +Thank you for considering contributing to PHPapp! This document provides guidelines and best practices to help you make your contributions effectively. + +--- + +## Table of Contents + +1. [How to Contribute](#how-to-contribute) +2. [Code of Conduct](#code-of-conduct) +3. [Development Workflow](#development-workflow) +4. [Pull Request Guidelines](#pull-request-guidelines) +5. [Reporting Issues](#reporting-issues) +6. [Community and Support](#community-and-support) + +--- + +## How to Contribute + +We welcome contributions of all kinds including bug fixes, new features, documentation improvements, and more. Here's how you can get started: + +1. **Fork the Repository**: Create a personal copy of the repository by forking it to your GitHub account. +2. **Clone the Repository**: Clone your fork to your local machine. + + ```bash + git clone https://github.com//phpapp.git + ``` + +3. **Create a Feature Branch**: Create a new branch for your change. + + ```bash + git checkout -b feature/your-feature-name + ``` + +4. **Write Clean Code**: Follow the project’s coding standards and structure. Familiarize yourself with the MVC (Model-View-Controller) architecture used in PHPapp. + +5. **Test Your Changes**: Ensure that your contribution doesn't break existing functionality. Add tests if applicable. + +6. **Commit and Push**: Write clear and descriptive commit messages. + + ```bash + git commit -m "feat: add feature description" + git push origin feature/your-feature-name + ``` + +7. **Open a Pull Request**: Head to the original repository and submit a pull request. + +--- + +## Code of Conduct + +Please adhere to the [Code of Conduct](CODE_OF_CONDUCT.md) to maintain a welcoming and inclusive community. Be respectful and constructive in your interactions. + +--- + +## Development Workflow + +### 1. Setting Up the Environment + +- Ensure you have PHP 8+ installed. +- Install dependencies using Composer: + + ```bash + composer install + ``` + +- Use the interactive installer to set up the project by visiting `http://yourdomain.com/installer.php`. + +### 2. Directory Structure + +The framework follows the MVC architecture. Key directories include: + +- `app/`: Contains models, views, and controllers. +- `core/`: Houses essential libraries such as `db.php`, `request.php`, and `response.php`. +- `static/`: Static files like CSS, JavaScript, and images. +- `config/`: Configuration files. + +Review the README for more details on the project's structure. + +--- + +## Pull Request Guidelines + +To ensure a smooth review process: + +- **Branch Naming Convention**: Use descriptive names such as `fix/issue-name` or `feature/feature-name`. +- **Write Descriptive Commit Messages**: Clearly explain the purpose of your changes. +- **Keep Changes Focused**: Avoid bundling unrelated changes in a single pull request. +- **Add Tests**: Include tests for new features or bug fixes. +- **Link Issues**: If your pull request addresses an issue, reference it in the description (e.g., `Fixes #123`). + +--- + +## Reporting Issues + +Found a bug or have a feature request? Open an [issue](https://github.com/and-ri/phpapp/issues) and provide the following: + +1. A clear and descriptive title. +2. Steps to reproduce the issue (if applicable). +3. Expected and actual behavior. +4. Screenshots, logs, or error messages (if available). + +--- + +## Community and Support + +For questions, discussions, or collaboration, feel free to: + +- Start a [GitHub Discussion](https://github.com/and-ri/phpapp/discussions). +- Join issues or pull request threads for ongoing topics. +- Reach out to the repository owner directly for critical matters. + +We appreciate your time and effort in contributing to PHPapp. Together, we can make it an even better framework for developers worldwide! \ No newline at end of file