diff --git a/.gitattributes b/.gitattributes index 3ef96b3..b02b913 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,9 @@ /tests export-ignore /.github export-ignore /README.md export-ignore +/CHANGELOG.md export-ignore /.gitignore export-ignore /.travis.yml export-ignore /phpunit.xml export-ignore -/sonar-project.properties export-ignore \ No newline at end of file +/sonar-project.properties export-ignore +/release-commit.php export-ignore \ No newline at end of file diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index f256b3c..761287e 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -7,8 +7,8 @@ on: branches: [ main ] jobs: - build: - + test: + name: Run Tests runs-on: ubuntu-latest strategy: @@ -16,17 +16,45 @@ jobs: steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP - uses: shivammathur/setup-php@2.30.0 + uses: shivammathur/setup-php@v2 with: php-version: 8.3 extensions: mbstring, sqlsrv, iconv - tools: phpunit, composer + tools: phpunit:9.5.20, composer - name: Install dependencies run: composer install --prefer-dist --no-progress - name: Execute Tests run: phpunit --configuration tests/phpunit.xml + + release_staging: + name: Prepare Beta Release Branch + needs: + - "test" + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/dev' + steps: + - uses: actions/checkout@v4 + - uses: google-github-actions/release-please-action@v3 + with: + release-type: php + default-branch: dev + config-file: release-please-config.json + token: ${{ secrets.GITHUB_TOKEN }} + release_prod: + name: Prepare Production Release Branch + needs: + - "test" + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + - uses: google-github-actions/release-please-action@v3 + with: + release-type: php + config-file: release-please-config.json + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 654efba..bb5b465 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ /nbproject/* -app/storage/* vendor/* -app/sto .idea/* .vscode/* tests/.phpunit.result.cache */config/* +*/Storage/* +*.cache diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c7af98e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +## [3.0.0-Beta.26](https://github.com/WebFiori/app/compare/v3.0.0-Beta.18...v3.0.0-Beta.26) (2025-04-09) + + +### Miscellaneous Chores + +* release v3.0.0-Beta.26 ([e21bbf5](https://github.com/WebFiori/app/commit/e21bbf5aedcbccaf83faff0e336561adaa72049c)) +* Updated Framework Version ([7416076](https://github.com/WebFiori/app/commit/74160762dafa7509d7bfd531062be1886979f7b2)) + +## [3.0.0-Beta.18](https://github.com/WebFiori/app/compare/v3.0.0-RC7...v3.0.0-Beta.18) (2024-12-04) + + +### Miscellaneous Chores + +* release v3.0.0-Beta.18 ([c82b989](https://github.com/WebFiori/app/commit/c82b98939167749b143c8bc86a325609ae6c4b5e)) +* Updated Composer Dependencies ([09827af](https://github.com/WebFiori/app/commit/09827af2d4d70b5e7d44d5c1234221528a70e3cf)) +* Updated Core Framework Version ([b6e00a3](https://github.com/WebFiori/app/commit/b6e00a3b8883d5736c2ccd96b8c0b8c5e0c025b1)) +* Updated Core Framework Version ([48623e3](https://github.com/WebFiori/app/commit/48623e383356957b2008fd09c90be94afdb7da29)) +* Updated Core Framework Version ([20ed7ea](https://github.com/WebFiori/app/commit/20ed7ea9939e2cf9339b10964ad5e0cc4b028749)) +* Updated Dependencies ([546eec2](https://github.com/WebFiori/app/commit/546eec25bff1736a0b3434243b80ed55df05e532)) +* Updated Framework Version ([bf81d5d](https://github.com/WebFiori/app/commit/bf81d5d746103d3491fd2e4ac54179dd587dbbce)) +* Updated Framework Version ([2df0e28](https://github.com/WebFiori/app/commit/2df0e2846121f7ed57350da2dc10488592362a89)) +* Updated Framework Version ([333ee5c](https://github.com/WebFiori/app/commit/333ee5c3f8d73388dc9d5889006568ce2413d20f)) +* Updated Framework Version ([17fb434](https://github.com/WebFiori/app/commit/17fb434209b611e7cfab5a6e6cd288fae924ab23)) +* Updated Framework Version ([57f362c](https://github.com/WebFiori/app/commit/57f362c61e572c5b3a1fe4d66c2f7bf9b89c7806)) diff --git a/README.md b/README.md index e1bdf02..41a1006 100644 --- a/README.md +++ b/README.md @@ -1,118 +1,107 @@ -# WebFiori Framework +# WebFiori App Template

- + WebFiori Logo

- - - - - - - - - - - - - + Build Status + Latest Release + Downloads

-## What is WebFiori Framework? +The default application template for [WebFiori Framework](https://github.com/WebFiori/framework). Use this as a starting point to create new WebFiori projects. -WebFiori Framework is a mini web development framework which is built using PHP language. The framework is fully object-oriented (OOP). It uses semi-MVC model, but it does not force it. The framework comes with many features which can help in making your website or web application up and running in no time. +## Requirements -## Supported PHP Versions -| Build Status | -|:-----------:| -|| -|| -|| -|| -|| -|| -|| -|
| +- PHP >= 8.1 +- [Composer](https://getcomposer.org/) +## Quick Start -## Key Features +```bash +composer create-project webfiori/app my-site +cd my-site +php -S localhost:8080 -t public +``` -* Provide minimum utilities to setup a small/medium web application. -* Theming and the ability to create multiple UIs for the same web app using any CSS or JavaScript framework. -* Building and manipulating the DOM of a web page inside PHP. -* Basic template engine. -* Fast and simple routing engine. -* Creation of web services (or APIs) that supports JSON with data filtering and validation. -* Middleware support for HTTP requests filtering before reaching application level. -* Basic support for MySQL and MSSQL schema and query building. -* Lightweight. The total size of framework core files is less than 3 megabytes. -* Access management by assigning system user a set of privileges. -* Customized sessions manager. -* Support for creating and sending nice-looking HTML emails. -* Autoload of user defined classes (loading composer packages also supported). -* Ability to create background tasks and let them run in specific time using CRON. -* Well-defined file upload and file handling sub-system. -* Basic support for creating CLI Applications. +Then open http://localhost:8080 in your browser. -## Standard Libraries +## Project Structure -Following table shows build status of the standard libraries that the framework is composed of. The build is based on the latest stable PHP release. +``` +├── public/ # Web server document root +│ ├── index.php # Application entry point +│ ├── .htaccess # Apache rewrite rules +│ ├── web.config # IIS rewrite rules +│ └── assets/ # Static files (CSS, JS, images) +├── tests/ # PHPUnit tests +│ ├── bootstrap.php # Test bootstrap +│ └── phpunit.xml # PHPUnit configuration +├── composer.json +├── php_cs.php.dist # PHP CS Fixer configuration +├── webfiori # CLI entry point (Linux/macOS) +└── webfiori.bat # CLI entry point (Windows) +``` -| Library | Build | Latest | -|----|----|----| -| [HTTP](https://github.com/WebFiori/http) | | | -| [File](https://github.com/WebFiori/file) | | | -| [Json](https://github.com/WebFiori/json) | | | -| [UI](https://github.com/WebFiori/ui) | | | -| [Collections](https://github.com/WebFiori/collections) | | | -| [Database](https://github.com/WebFiori/database) | | | -| [CLI](https://github.com/WebFiori/cli) | | | -| [Mailer](https://github.com/WebFiori/mail) | | | -| [Errors and Exceptions Handler](https://github.com/WebFiori/err) | | | +After running `composer create-project`, the framework will generate an `App/` directory containing your application code (routes, middleware, commands, etc.). -## Problems Solved +## Customizing the App Directory -One of the things that any developer cares about any software project is the problem or problems it solves. As for WebFiori framework, It can help in solving the following problems: -* The ability to create a customized links to web pages as needed by using [Routing](https://webfiori.com/learn/routing). -* No need for touching HTML to play with the DOM by using [UI Library](https://webfiori.com/learn/ui-package) of the framework. -* Run PHP code as a CRON task through HTTP protocol or through terminal as a [Background Job](https://webfiori.com/learn/background-tasks). -* Changing whole user interface by changing one line of code through [Theming](https://webfiori.com/learn/themes). -* Ability to move the source code of the web application without having to do a lot of re-configuration. -* [Sending HTML email](https://webfiori.com/learn/sending-emails) messages with attachments without having to write a lot of code. -* Solved the issues which are found in default PHP session management implementation by implementing a custom [Sessions Management System](https://webfiori.com/learn/sessions-management). -* Reduce the number of dependencies at which a developer need to set up a web application. +By default, the framework uses `App/` as the application root directory. To change this, edit the first parameter of `App::initiate()` in `public/index.php`: -## Getting Started +```php +App::initiate('MyApp', 'public', __DIR__); +``` -To learn the basics of how to use the framework, please head on to https://webfiori.com/learn. You can also read same docs which can be found in [docs repo](https://github.com/usernane/wf-docs). In addition to that, you can read the API docs of the framework at [the official website](https://webfiori.com/docs). +Reasons you might want to rename it: +- Gives your project a distinct identity instead of a generic `App/` folder. +- Avoids naming conflicts if you're integrating WebFiori into an existing project that already has an `App/` directory. +- Makes it easier to distinguish between multiple WebFiori-based projects in the same workspace. -## Setup +## Running Tests -### Local Development Environment +```bash +composer test +``` -If you plan to test the framework on your local machine, the recommended way is to have AMP stack (Apache, MySQL and PHP). There are many available online. We suggest to use the ones that are offered by Bitnami. You can go to https://bitnami.com/stacks/infrastructure to check the available options. +## Code Style -After installing AMP stack, you can either use composer to install the framework or install it manually by download it through https://webfiori.com/download. If you plan to use composer, then you must first download composer from their website: https://getcomposer.org/download/. Once downloaded, place the `.phar` file in the folder `htdocs` or your server root. Once you do that, run the terminal in `htdocs` and run the following command: +This project uses [PHP CS Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) for code style enforcement. +```bash +composer cs-check # Check for violations (dry run) +composer cs-fix # Auto-fix violations ``` -php composer.phar create-project --prefer-dist webfiori/app my-site + +## CLI Usage + +WebFiori includes a CLI tool for common tasks: + +```bash +# Linux/macOS +php webfiori + +# Windows +webfiori.bat ``` -This command will create new folder with the name `my-site` and install the framework inside it. -For more information about how to set up the framework, [check here](https://webfiori.com/learn/installation). +## Documentation + +- [Getting Started](https://webfiori.com/learn) +- [API Reference](https://webfiori.com/docs) +- [Framework Repository](https://github.com/WebFiori/framework) +## Contributing -## Contribution +For information on how to contribute, see [the contribution guide](https://webfiori.com/contribute). -For information on how to contribute to the project, [check here](https://webfiori.com/contribute). +## Reporting Issues -## Notes -* If you think that there is a better way of doing things or wants new feature, feel free to [drop an issue](https://github.com/WebFiori/framework/issues/new). -* To report security vulnerabilities, please email [ibrahim@webfiori.com](mailto:ibrahim@webfiori.com). +- For bugs and feature requests, [open an issue](https://github.com/WebFiori/app/issues/new). +- For security vulnerabilities, please email [ibrahim@webfiori.com](mailto:ibrahim@webfiori.com). ## License -The project is licensed under MIT license. +This project is licensed under the [MIT License](LICENSE). diff --git a/app/config/app-config-prod.json b/app/config/app-config-prod.json deleted file mode 100644 index 3a77b09..0000000 --- a/app/config/app-config-prod.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "base-url":"DYNAMIC", - "theme":null, - "home-page":"BASE_URL", - "primary-lang":"EN", - "titles":{ - "AR":"افتراضي", - "EN":"Default" - }, - "name-separator":"|", - "scheduler-password":"NO_PASSWORD", - "app-names":{ - "AR":"تطبيق", - "EN":"Application" - }, - "app-descriptions":{ - "AR":"", - "EN":"" - }, - "version-info":{ - "version":"1.0", - "version-type":"Stable", - "release-date":"2024-01-16" - }, - "env-vars":{ - "WF_VERBOSE":{ - "value":false, - "description":"Configure the verbosity of error messsages at run-time. This should be set to true in testing and false in production." - }, - "CLI_HTTP_HOST":{ - "value":"example.com", - "description":"Host name that will be used when runing the application as command line utility." - } - }, - "smtp-connections":{ - }, - "database-connections":{ - } -} \ No newline at end of file diff --git a/app/config/app-config-staging.json b/app/config/app-config-staging.json deleted file mode 100644 index f09dcf9..0000000 --- a/app/config/app-config-staging.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "base-url":"DYNAMIC", - "theme":null, - "home-page":"BASE_URL", - "primary-lang":"EN", - "titles":{ - "AR":"افتراضي", - "EN":"Default" - }, - "name-separator":"|", - "scheduler-password":"NO_PASSWORD", - "app-names":{ - "AR":"تطبيق", - "EN":"Application" - }, - "app-descriptions":{ - "AR":"", - "EN":"" - }, - "version-info":{ - "version":"1.0", - "version-type":"Stable", - "release-date":"2024-01-16" - }, - "env-vars":{ - "WF_VERBOSE":{ - "value":true, - "description":"Configure the verbosity of error messsages at run-time. This should be set to true in testing and false in production." - }, - "STAGING":{ - "value":true, - "description":"Indicate if in staging environment or not." - }, - "CLI_HTTP_HOST":{ - "value":"example.com", - "description":"Host name that will be used when runing the application as command line utility." - } - }, - "smtp-connections":{ - }, - "database-connections":{ - } -} \ No newline at end of file diff --git a/app/config/app-config-testing.json b/app/config/app-config-testing.json deleted file mode 100644 index db4d733..0000000 --- a/app/config/app-config-testing.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "base-url":"DYNAMIC", - "theme":null, - "home-page":"BASE_URL", - "primary-lang":"EN", - "titles":{ - "AR":"افتراضي", - "EN":"Default" - }, - "name-separator":"|", - "scheduler-password":"NO_PASSWORD", - "app-names":{ - "AR":"تطبيق", - "EN":"Application" - }, - "app-descriptions":{ - "AR":"", - "EN":"" - }, - "version-info":{ - "version":"1.0", - "version-type":"Stable", - "release-date":"2024-01-16" - }, - "env-vars":{ - "WF_VERBOSE":{ - "value":false, - "description":"Configure the verbosity of error messsages at run-time. This should be set to true in testing and false in production." - }, - "TESTING":{ - "value":true, - "description":"Indicates if in testing environment or not." - }, - "CLI_HTTP_HOST":{ - "value":"example.com", - "description":"Host name that will be used when runing the application as command line utility." - } - }, - "smtp-connections":{ - }, - "database-connections":{ - } -} \ No newline at end of file diff --git a/app/ini/InitAutoLoad.php b/app/ini/InitAutoLoad.php deleted file mode 100644 index b493d48..0000000 --- a/app/ini/InitAutoLoad.php +++ /dev/null @@ -1,14 +0,0 @@ -=7.0", - "webfiori/framework":"v3.0.0-Beta.14" + "php": ">=8.1", + "webfiori/framework": "v3.0.0-RC0" }, - "keywords": [ - "framework", - "webfiori", - "php", - "API", - "Web APIs", - "Themes" - ], - "license": "MIT" + "require-dev": { + "phpunit/phpunit": "^11", + "friendsofphp/php-cs-fixer": "^3" + }, + "scripts": { + "test": "phpunit --configuration tests/phpunit.xml", + "cs-fix": "php-cs-fixer fix --config=php_cs.php.dist", + "cs-check": "php-cs-fixer fix --config=php_cs.php.dist --dry-run --diff" + } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index bc60745..0000000 --- a/composer.lock +++ /dev/null @@ -1,610 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "7d6713d2033cddbc85bf171d79a7a079", - "packages": [ - { - "name": "webfiori/cli", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/cli.git", - "reference": "d9fc5819dd7024a4aef4cb28775ea892014c08ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/cli/zipball/d9fc5819dd7024a4aef4cb28775ea892014c08ab", - "reference": "d9fc5819dd7024a4aef4cb28775ea892014c08ab", - "shasum": "" - }, - "require": { - "webfiori/file": "1.3.*" - }, - "bin": [ - "bin/wfc" - ], - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\cli\\": "webfiori\\cli" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ibrahim", - "email": "ibrahim@webfiori.com" - } - ], - "description": "Class library to simplify the process of creating command line based applications using PHP.", - "keywords": [ - "cli", - "command line", - "php", - "terminal" - ], - "support": { - "issues": "https://github.com/WebFiori/cli/issues", - "source": "https://github.com/WebFiori/cli/tree/v1.3.0" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-08-20T21:10:05+00:00" - }, - { - "name": "webfiori/collections", - "version": "v1.1.4", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/collections.git", - "reference": "e82f0418c298de0c534cf6b1f84b703207c40b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/collections/zipball/e82f0418c298de0c534cf6b1f84b703207c40b5b", - "reference": "e82f0418c298de0c534cf6b1f84b703207c40b5b", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\collections\\": "webfiori\\collections" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Basic collections set used by WebFiori.", - "keywords": [ - "collection", - "collections", - "data structures", - "library", - "webfiori" - ], - "support": { - "issues": "https://github.com/WebFiori/collections/issues", - "source": "https://github.com/WebFiori/collections/tree/v1.1.4" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2023-12-08T22:02:45+00:00" - }, - { - "name": "webfiori/database", - "version": "v0.8.11", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/database.git", - "reference": "fda0e183437061bc75fa3422836433a440baa8c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/database/zipball/fda0e183437061bc75fa3422836433a440baa8c0", - "reference": "fda0e183437061bc75fa3422836433a440baa8c0", - "shasum": "" - }, - "require": { - "webfiori/jsonx": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\database\\": "webfiori\\database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Database abstraction layer of WebFiori framework.", - "keywords": [ - "database", - "library", - "mysql", - "php", - "query builder" - ], - "support": { - "issues": "https://github.com/WebFiori/database/issues", - "source": "https://github.com/WebFiori/database/tree/v0.8.11" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-10-28T20:25:53+00:00" - }, - { - "name": "webfiori/err", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/err.git", - "reference": "dbd6624667e0be7424a48da821ec89a02122ed60" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/err/zipball/dbd6624667e0be7424a48da821ec89a02122ed60", - "reference": "dbd6624667e0be7424a48da821ec89a02122ed60", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ibrahim BinAlshikh", - "email": "ibrahim@webfiori.com" - } - ], - "description": "A library for handling PHP errors and exceptions in a better way.", - "keywords": [ - "error", - "error handler", - "errors", - "exception", - "php" - ], - "support": { - "issues": "https://github.com/WebFiori/err/issues", - "source": "https://github.com/WebFiori/err/tree/v1.1.0" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-06-26T21:03:32+00:00" - }, - { - "name": "webfiori/file", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/file.git", - "reference": "badb7251fb8362abfebc51f90d4c97d12e502f15" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/file/zipball/badb7251fb8362abfebc51f90d4c97d12e502f15", - "reference": "badb7251fb8362abfebc51f90d4c97d12e502f15", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "webfiori/jsonx": "3.3.x" - }, - "require-dev": { - "webfiori/http": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\file\\": "webfiori\\file" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ibrahim BinAlshikh", - "email": "ibrahim@webfiori.com" - } - ], - "description": "Basic class library to read, write and view files using PHP.", - "keywords": [ - "file", - "files", - "php", - "upload", - "uploading" - ], - "support": { - "issues": "https://github.com/WebFiori/file/issues", - "source": "https://github.com/WebFiori/file/tree/v1.3.6" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-04-29T20:08:30+00:00" - }, - { - "name": "webfiori/framework", - "version": "3.0.0-Beta.14", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/framework.git", - "reference": "ffba40f52f419b6d1b93620757d5e85360d64938" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/framework/zipball/ffba40f52f419b6d1b93620757d5e85360d64938", - "reference": "ffba40f52f419b6d1b93620757d5e85360d64938", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-json": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "php": ">=7.0", - "webfiori/cli": "v1.3.0", - "webfiori/collections": "v1.1.4", - "webfiori/database": "v0.8.11", - "webfiori/err": "v1.1.0", - "webfiori/file": "v1.3.6", - "webfiori/http": "v3.3.15", - "webfiori/jsonx": "v3.3.0", - "webfiori/mailer": "v1.2.0", - "webfiori/ui": "v2.6.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\framework\\": "webfiori/framework/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ibrahim BinAlshikh", - "email": "ibrahim@webfiori.com", - "homepage": "https://ibrahim-binalshikh.me", - "role": "Maintainer" - } - ], - "description": "WebFiori framework. Made to make the web bloom.", - "homepage": "https://webfiori.com", - "keywords": [ - "Web APIs", - "api", - "framework", - "php", - "themes", - "webfiori" - ], - "support": { - "issues": "https://github.com/webfiori/framework/issues", - "source": "https://github.com/webfior/framework" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-11-21T09:29:08+00:00" - }, - { - "name": "webfiori/http", - "version": "v3.3.15", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/http.git", - "reference": "842d9aed0bdf96dd45b44b03f9a04fa8ee7d895d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/http/zipball/842d9aed0bdf96dd45b44b03f9a04fa8ee7d895d", - "reference": "842d9aed0bdf96dd45b44b03f9a04fa8ee7d895d", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "php": ">=7.0", - "webfiori/jsonx": "3.3.x" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\http\\": "webfiori\\http" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Basic library that can help in creating RESTful APIs using PHP.", - "keywords": [ - "Web APIs", - "api", - "http", - "json", - "jsonx", - "library", - "php", - "psr-7" - ], - "support": { - "issues": "https://github.com/WebFiori/http/issues", - "source": "https://github.com/WebFiori/http/tree/v3.3.15" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - } - ], - "time": "2024-11-20T20:47:16+00:00" - }, - { - "name": "webfiori/jsonx", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/json.git", - "reference": "833fd51516cce33e9bcc2efd0e81956b541ae7dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/json/zipball/833fd51516cce33e9bcc2efd0e81956b541ae7dc", - "reference": "833fd51516cce33e9bcc2efd0e81956b541ae7dc", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\json\\": "webfiori\\json" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHP library for creating well-formatted JSON strings.", - "keywords": [ - "json", - "jsonx", - "php" - ], - "support": { - "issues": "https://github.com/WebFiori/json/issues", - "source": "https://github.com/WebFiori/json/tree/v3.3.0" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - } - ], - "time": "2023-08-03T07:59:28+00:00" - }, - { - "name": "webfiori/mailer", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/mail.git", - "reference": "e5b61fb9d8bc27c4c2ac8106a98ec7d1335cd65e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/mail/zipball/e5b61fb9d8bc27c4c2ac8106a98ec7d1335cd65e", - "reference": "e5b61fb9d8bc27c4c2ac8106a98ec7d1335cd65e", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "webfiori/file": "*", - "webfiori/ui": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\email\\": "webfiori\\email" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ibrahim BinAlshikh", - "email": "ibrahim@webfiori.com" - } - ], - "description": "Sockets-based library for sending HTML email messages.", - "keywords": [ - "email", - "html", - "mail", - "php", - "sockets" - ], - "support": { - "issues": "https://github.com/WebFiori/mail/issues", - "source": "https://github.com/WebFiori/mail/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - }, - { - "url": "https://www.buymeacoffee.com/ibrahimdev", - "type": "custom" - }, - { - "url": "https://ko-fi.com/ibrahimdev", - "type": "ko_fi" - } - ], - "time": "2024-04-14T16:06:30+00:00" - }, - { - "name": "webfiori/ui", - "version": "v2.6.3", - "source": { - "type": "git", - "url": "https://github.com/WebFiori/ui.git", - "reference": "c6d0b13ff0d69473cdef5560edadb67032128150" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WebFiori/ui/zipball/c6d0b13ff0d69473cdef5560edadb67032128150", - "reference": "c6d0b13ff0d69473cdef5560edadb67032128150", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "webfiori/collections": "1.1.x" - }, - "require-dev": { - "phpunit/phpunit": "^5" - }, - "type": "library", - "autoload": { - "psr-4": { - "webfiori\\ui\\": "webfiori\\ui" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A library that provides basic utilities for creating HTML documents.", - "keywords": [ - "code", - "dom", - "html", - "library", - "webfiori" - ], - "support": { - "issues": "https://github.com/WebFiori/ui/issues", - "source": "https://github.com/WebFiori/ui/tree/v2.6.3" - }, - "funding": [ - { - "url": "https://paypal.me/IbrahimBinAlshikh", - "type": "custom" - } - ], - "time": "2024-07-08T22:04:06+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "webfiori/framework": 10 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=7.0" - }, - "platform-dev": [], - "plugin-api-version": "2.3.0" -} diff --git a/php_cs.php.dist b/php_cs.php.dist new file mode 100644 index 0000000..e06ef66 --- /dev/null +++ b/php_cs.php.dist @@ -0,0 +1,98 @@ +exclude('vendor') + ->in(__DIR__) +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + 'align_multiline_comment' => [ + 'comment_type' => 'phpdocs_only' + ], + 'array_indentation' => true, + 'array_syntax' => [ + 'syntax' => 'short' + ], + 'binary_operator_spaces' => [ + 'default' => 'single_space' + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'if','return','while','for','foreach','do' + ] + ], + 'indentation_type' => true, + 'method_chaining_indentation' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_after_namespace' => true, + 'elseif' => false, + 'explicit_string_variable' => false, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'line_ending' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_unused_imports' => true, + 'single_import_per_statement' => true, + 'single_blank_line_at_eof' => true, + 'no_whitespace_in_blank_line' => true, + 'not_operator_with_space' => false, + 'ordered_imports' => [ + 'sort_algorithm' => 'alpha' + ], + 'ordered_class_elements' => [ + 'sort_algorithm' => 'alpha', + 'order' => [ + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public', + 'property_protected', + 'property_private', + 'construct', + 'method_public', + 'method_private' + ] + ], + 'no_mixed_echo_print' => [ + 'use' => 'echo' + ], + 'constant_case' => [ + 'case' => 'lower' + ], + 'increment_style' => [ + 'style' => 'post' + ], + 'concat_space' => [ + 'spacing' => 'none' + ], + 'braces' => [ + 'allow_single_line_closure' => false, + 'position_after_functions_and_oop_constructs' => 'same', + 'position_after_anonymous_constructs' => 'next', + 'position_after_control_structures' => 'same' + ], + 'class_definition' => [ + 'single_line' => true + ] + ]) + ->setIndent(" ") + ->setLineEnding("\n") + ->setFinder($finder) +; \ No newline at end of file diff --git a/public/index.php b/public/index.php index f081333..6b77be5 100644 --- a/public/index.php +++ b/public/index.php @@ -1,88 +1,17 @@ loadAppClass(); - App::setConfigDriver('\\webfiori\\framework\\config\\JsonDriver'); - /** - * This where magic will start. - * - * Planting application seed into the ground and make your work bloom. - */ - App::start(); - - if (App::getRunner()->isCLI() === true) { - App::getRunner()->start(); - } else { - //route user request. - SessionsManager::start('wf-session'); - Router::route(Request::getRequestedURI()); - Response::send(); - } - } - /** - * Try to load the class 'App'. - * - * @throws Exception - */ - private function loadAppClass() { - $DS = DIRECTORY_SEPARATOR; - $frameworkPath = ROOT_PATH.$DS.'vendor'.$DS.'webfiori'.$DS.'framework'; - $corePath = $frameworkPath.$DS.'webfiori'.$DS.'framework'; - $rootClass = $DS.'App.php'; - - if (file_exists($corePath.$rootClass)) { - define('WF_CORE_PATH', $corePath); - require_once $corePath.$rootClass; - } else { - throw new Exception('Unable to locate the class "App".'); - } - } - /** - * Creates a single instance of the class. - */ - public static function create() { - if (self::$instance === null) { - self::$instance = new Index(); - } - } +// First parameter is the name of the application directory. +try { + App::initiate('App', 'public', __DIR__); + App::start(); + App::handle(); +} catch (\Throwable $e) { + http_response_code(500); + echo 'Internal Server Error'; } -Index::create(); \ No newline at end of file diff --git a/release-commit.php b/release-commit.php new file mode 100644 index 0000000..3cb8f8f --- /dev/null +++ b/release-commit.php @@ -0,0 +1,9 @@ +assertTrue(true); + } + + protected function setUp(): void { + parent::setUp(); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8261371..c5589a1 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,123 +1,64 @@ [ - 'tests', - 'webfiori', - 'vendor', - APP_DIR, - ], - 'define-root' => true, - 'root' => $Root, - 'on-load-failure' => 'do-nothing' -]); -fprintf(STDOUT,'Autoloader Initialized.'."\n"); - -fprintf(STDOUT,"Initializing application...\n"); -define('APP_PATH', ClassLoader::get()->root().$DS.APP_DIR.$DS); -fprintf(STDOUT,'App Path: '.APP_PATH."\n"); -$driver = "\\webfiori\\framework\\config\\JsonDriver"; -fprintf(STDOUT,"Setting application configuration driver to '$driver'\n"); -App::setConfigDriver($driver); -$configFileName = 'app-config-testing.json'; -fprintf(STDOUT,"Setting application configuration file to '$configFileName'\n"); -App::getConfig()->setConfigFileName($configFileName); -App::getConfig()->initialize(); -App::start(); -fprintf(STDOUT,'Done.'."\n"); -fprintf(STDOUT,'Root Directory: \''.ClassLoader::get()->root().'\'.'."\n"); -define('TESTS_PATH', ClassLoader::get()->root().$DS.'tests'); -fprintf(STDOUT,'Stored Connections:'."\n"); -if (count(App::getConfig()->getDBConnections()) != 0) { - foreach (App::getConfig()->getDBConnections() as $conn) { - fprintf(STDOUT, $conn->getName()."\n"); - } -} else { - fprintf(STDOUT, "<>\n"); +$root = dirname(__DIR__); +fwrite(STDOUT, "Root: ".$root."\n"); +require $root.'/vendor/autoload.php'; + +use WebFiori\Framework\App; + +fwrite(STDOUT, "Initializing App...\n"); +try { + App::initiate('App', 'public', $root.'/public'); + App::start(); +} catch (Throwable $e) { + fwrite(STDOUT, "Error During Initialization: ".$e->getMessage()."\n"); + exit(1); } -fprintf(STDOUT, "Registering shutdown function...\n"); -register_shutdown_function(function() -{ - //TODO: Run extra code after tests completion. - fprintf(STDOUT, "Testing Finished.\n"); -}); -fprintf(STDOUT, "Registering shutdown function completed.\n"); -require_once 'query-runner.php'; - -//TODO: Include your own custom bootstrap scripts here. -//require_once 'my-script.php'; - -fprintf(STDOUT, "Done\n"); -fprintf(STDOUT,"Starting to run tests...\n"); \ No newline at end of file +fwrite(STDOUT, "Done\n"); +fwrite(STDOUT, "----------------------------------------------\n"); + +//TODO: Add Database Connections and run migrations, or remove this block + +//fwrite(STDOUT, "Adding Database Connection...\n"); +// +// $exitCode = App::getRunner()->setArgsVector([ +// 'webfiori', +// 'add:db-connection', +// '--db-type' => 'mysql', +// '--host' => getenv('DB_HOST'), +// '--port' => '3306', +// '--user' => getenv('DB_USER'), +// '--password' => getenv('DB_PASS'), +// '--database' => 'db_name', +// '--name' => 'my-connection', +// '--no-check' +// ])->start(); + +// if ($exitCode != 0) { +// fwrite(STDOUT, "Error During Initialization. Tests Will not Execute\n"); +// fwrite(STDOUT, "----------------------------------------------\n"); +// exit($exitCode); +// } +// fwrite(STDOUT, "Done\n"); +// fwrite(STDOUT, "----------------------------------------------\n"); + +// fwrite(STDOUT, "Applying Migrations...\n"); +// $exitCode = App::getRunner()->setArgsVector([ +// 'webfiori', +// 'migrations:fresh', +// '--connection' => 'my-connection', +// '--env' => 'dev' +// ])->start(); +// if ($exitCode != 0) { +// fwrite(STDOUT, "Error During Initialization. Tests Will not Execute\n"); +// fwrite(STDOUT, "----------------------------------------------\n"); +// exit($exitCode); +// } + +//TODO: Routines after testing. Or Remove +// register_shutdown_function(function () { + +// }); +// fwrite(STDOUT, "----------------------------------------------\n"); +fwrite(STDOUT, "Bootstrapping Done\n"); +fwrite(STDOUT, "----------------------------------------------\n"); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index a02abf2..25c4ba9 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -1,22 +1,11 @@ - - - - - - - - - - - - + - - - - ./sample + + Apis - - \ No newline at end of file + diff --git a/tests/query-runner.php b/tests/query-runner.php deleted file mode 100644 index 7e7a863..0000000 --- a/tests/query-runner.php +++ /dev/null @@ -1,45 +0,0 @@ -setArgsVector([ - 'webfiori', - 'run-query', - '--no-confirm', - '--create', - '--file' => $queryFileOrSchema, - '--connection' => $connection, - '--ansi', - ]); - } else { - fprintf(STDOUT, "Using Schema ".$queryFileOrSchema."...\n"); - App::getRunner()->setArgsVector([ - 'webfiori', - 'run-query', - '--no-confirm', - '--create', - '--schema' => $queryFileOrSchema, - '--ansi', - ]); - } - App::getRunner()->start(); -} diff --git a/tests/sample/SampleTest.php b/tests/sample/SampleTest.php deleted file mode 100644 index 34f95b7..0000000 --- a/tests/sample/SampleTest.php +++ /dev/null @@ -1,17 +0,0 @@ -assertTrue(App::getConfig() instanceof JsonDriver); - } -} diff --git a/themes/bootstrap-based/BootstrapTheme.php b/themes/bootstrap-based/BootstrapTheme.php deleted file mode 100644 index 1dcc167..0000000 --- a/themes/bootstrap-based/BootstrapTheme.php +++ /dev/null @@ -1,119 +0,0 @@ -setVersion('1.0'); - $this->setAuthor('Ibrahim'); - $this->setName('Bootstrap Theme'); - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - - $page->getChildByID('page-body')->setClassName('row'); - $page->getDocument()->getBody()->setClassName('container-fluid'); - $page->getChildByID('main-content-area')->setClassName('col'); - $breadCrump = new HTMLNode('nav'); - $breadCrump->setClassName('col'); - $page->getChildByID('main-content-area')->addChild($breadCrump); - $breadCrump->setAttribute('aria-label', 'breadcrumb'); - $olBr = new HTMLNode('ol'); - $olBr->setClassName('breadcrumb'); - $breadCrump->addChild($olBr); - $li = new ListItem(); - $li->setAttribute('aria-current', 'page'); - $li->addTextNode($page->getTitle()); - $li->setClassName('breadcrumb-item active'); - $olBr->addChild($li); - }); - } - /** - * - * @param type $options - * @return HTMLNode - */ - public function createHTMLNode($options = []) { - $type = isset($options['type']) ? $options['type'] : 'div'; - - if ($type == 'row') { - $node = new HTMLNode(); - $node->setClassName('row'); - - return $node; - } else if ($type == 'container') { - $node = new HTMLNode(); - $node->setClassName('container'); - - return $node; - } else if ($type == 'container-f') { - $node = new HTMLNode(); - $node->setClassName('container-fluid'); - - return $node; - } else { - $node = new HTMLNode(); - - return $node; - } - } - /** - * - * @return HTMLNode - */ - public function getAsideNode() { - $node = new HTMLNode(); - $node->setClassName('col-2'); - - return $node; - } - - public function getFooterNode() { - $node = $this->createHTMLNode(['type' => 'row']); - - return $node; - } - - public function getHeadNode() { - $node = new HeadNode(); - $node->addCSS('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css', [ - 'integrity' => 'sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T', - 'crossorigin' => 'anonymous' - ], false); - $node->addJs('https://code.jquery.com/jquery-3.3.1.slim.min.js', [ - 'integrity' => 'sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo', - 'crossorigin' => 'anonymous' - ], false); - $node->addJs('https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js', [ - 'integrity' => 'sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1', - 'crossorigin' => 'anonymous' - ], false); - $node->addJs('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js', [ - 'integrity' => 'sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM', - 'crossorigin' => 'anonymous' - ], false); - - return $node; - } - - public function getHeaderNode() { - $node = $this->createHTMLNode(['type' => 'row']); - $topNav = HTMLNode::loadComponent($this->getDirecotry().'header.html', [ - // TODO: Supply values for placeholders. - ]); - $node->addChild($topNav); - - return $node; - } -} - -return __NAMESPACE__; diff --git a/themes/bootstrap-based/header.html b/themes/bootstrap-based/header.html deleted file mode 100644 index f40e5c6..0000000 --- a/themes/bootstrap-based/header.html +++ /dev/null @@ -1,34 +0,0 @@ - \ No newline at end of file diff --git a/themes/greeny/GreenyTheme.php b/themes/greeny/GreenyTheme.php deleted file mode 100644 index 1ea8144..0000000 --- a/themes/greeny/GreenyTheme.php +++ /dev/null @@ -1,100 +0,0 @@ -setAuthor('Ibrahim Ali'); - $this->setAuthorUrl('http://ibrahim-2017.blogspot.com'); - $this->setName('Greeny By Ibrahim Ali'); - $this->setVersion('1.0'); - $this->setLicenseName('MIT License'); - $this->setLicenseUrl('https://opensource.org/licenses/MIT'); - $this->setDescription('First theme ever made. A nice green colored elements That ' - .'makes you thing about the nature. Use it as a template and a guide for creating ' - .'new themes.'); - $this->setImagesDirName('images'); - $this->setJsDirName('js'); - $this->setCssDirName('css'); - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - $page->getDocument()->getBody()->setClassName('pa-container'); - $page->getDocument()->getChildByID('page-body')->setClassName('pa-row'); - - if ($page->hasAside()) { - $page->getDocument()->getChildByID('side-content-area')->setClassName('pa-'.Page::dir().'-col-2 show-border'); - $page->getDocument()->getChildByID('main-content-area')->setClassName('pa-'.Page::dir().'-col-10 show-border'); - } else { - $page->getDocument()->getChildByID('main-content-area')->setClassName('pa-'.Page::dir().'-col-12 show-border'); - } - $page->getDocument()->getChildByID('main-content-area')->addTextNode('Main Content Area.'); - }); - $this->setBeforeLoaded(function() - { - }); - } - - public function createHTMLNode($options = []) { - $node = new HTMLNode(); - - return $node; - } - public function getAsideNode() { - $menu = new HTMLNode('div'); - $menu->addTextNode('Aside'); - - return $menu; - } - - public function getFooterNode() { - $node = new HTMLNode('div'); - $node->setAttribute('class', 'pa-row'); - $fNode = new HTMLNode('footer'); - $fNode->setAttribute('dir', Page::dir()); - $fNode->setAttribute('class','pa-'.Page::dir().'-col-12 show-border'); - $fNode->setAttribute('itemtype','http://schema.org/WPFooter'); - $fNav = new HTMLNode('nav'); - $fNavUl = new HTMLNode('ul'); - $fNav->addChild($fNavUl); - $fNode->addChild($fNav); - $node->addChild($fNode); - $div = new HTMLNode('div'); - $div->setAttribute('class', 'pa-ltr-col-twelve'); - $div->addTextNode('Powered By: WebFiori Framework v'.WF_VERSION.' ('.WF_VERSION_TYPE.')',false); - $fNode->addChild($div); - - return $node; - } - - public function getHeadNode() { - $headTag = new HeadNode(); - $headTag->setBase(WebFioriApp::getAppConfig()->getBaseURL()); - $headTag->addLink('icon', Page::imagesDir().'/favicon.png'); - $headTag->setCanonical(WebFioriApp::getAppConfig()->getBaseURL().Page::canonical()); - - $headTag->addMeta('robots', 'index, follow'); - - return $headTag; - } - - public function getHeaderNode() { - $headerSec = new HTMLNode(); - $headerSec->setClassName('pa-row'); - $headerBody = new HTMLNode(); - $headerBody->setClassName('pa-'.Page::dir().'-col-12 show-border'); - $headerBody->setWritingDir(Page::dir()); - $headerBody->addTextNode('Header Sec'); - $headerSec->addChild($headerBody); - - return $headerSec; - } -} - -return __NAMESPACE__; diff --git a/themes/ibrahim/BasePage.php b/themes/ibrahim/BasePage.php deleted file mode 100644 index 726ca8e..0000000 --- a/themes/ibrahim/BasePage.php +++ /dev/null @@ -1,356 +0,0 @@ -setTheme(IbrahimTheme::class); - $this->jsonData = new Json([ - 'rtl' => $this->getTranslation()->getWritingDir() == 'rtl', - 'darkTheme' => new Json([ - 'primary' => '#8bc34a', - 'secondary' => '#4caf50', - 'accent' => '#795548', - 'error' => '#f44336', - 'warning' => '#ff9800', - 'info' => '#607d8b', - 'success' => '#00bcd4' - ]), - 'lightTheme' => new Json([ - 'primary' => '#8bc34a', - 'secondary' => '#4caf50', - 'accent' => '#795548', - 'error' => '#f44336', - 'warning' => '#ff9800', - 'info' => '#607d8b', - 'success' => '#00bcd4' - ]) - ]); - - if (strlen($vueScript) != 0) { - $this->setVueJs($vueScript); - } else { - $this->setVueJs('assets/ibrahim/default.js'); - } - $this->setTitle($pageTitle); - $this->setDescription($description); - $this->insert($this->getTheme()->createHTMLNode([ - 'name' => 'heading', - 'title' => $pageTitle - ])); - $this->addBeforeRender(function(BasePage $thisPage) - { - $snackBarsCount = 4; - $snackbarsJsonArr = []; - - for ($x = 0 ; $x < $snackBarsCount ; $x++) { - $node = new HTMLNode('v-snackbar', [ - 'v-model' => "snackbars[$x].snackbar", - ':color' => "snackbars[$x].statusColor", - ':timeout' => "snackbars[$x].snackbarTimeout", - ]); - - $node->addChild('v-icon') - ->text("{{snackbars[$x].icon}}"); - $node->addChild('div', [ - 'v-html' => "snackbars[$x].statusText", - 'style' => [ - 'display' => 'inline' - ] - ]); - $node->addChild('template', [ - 'v-slot:action' => '{attrs}' - ])->addChild('v-btn', [ - '@click' => "snackbars[$x].snackbar = false", - 'v-bind' => "attrs", - ':color' => "snackbars[$x].statusColor", - 'icon' - ])->addChild('v-icon', [ - 'color' => 'white' - ])->text('mdi-close-circle'); - - $snackbarsJsonArr[] = new Json([ - 'snackbar' => false, - 'statusColor' => 'green', - 'snackbarTimeout' => 5000, - 'statusText' => 'Hello', - 'icon' => 'mdi-information' - ]); - $thisPage->insert($node); - } - - $thisPage->addToJson([ - 'snackbars' => $snackbarsJsonArr - ]); - - - if ($thisPage->isDark()) { - $css = new HTMLNode('style'); - $css->addTextNode("input{color:white;}"); - $thisPage->getDocument()->getHeadNode()->addChild($css); - } - - $thisPage->addInlineJs('window.data = '.$thisPage->getJson().';'); - }); - $this->topInlineJs = new JsCode(); - - $this->getDocument()->getHeadNode()->addChild($this->topInlineJs); - $this->_checkIsDark(); - } - /** - * Adds an inline JavAscript code to the >head< tag of the page. - * - * this is mainly used to initialize JavAscript variables that might be used - * in front-end. - * - * @param string $code A valid JavaScript code as string. - */ - public function addInlineJs($code) { - $this->getTopInlineJs()->addCode($code."\n"); - } - /** - * Adds a set of attributes to the json data. - * - * @param array $arrOfAttrs An associative array. The indices of the array - * are attributes names and the value of each index is the value that will - * be passed. - */ - public function addToJson($arrOfAttrs) { - foreach ($arrOfAttrs as $attrKey => $attrVal) { - $this->getJson()->add($attrKey, $attrVal); - } - } - /** - * Creates a v-btn element. - * - * @param array $props An associative array that holds button attributes. - * - * @param string $text An optional button text. - * - * @param string $icon An optional icon to add to the button. The value of - * this argument must be of the mdi- icons set. - * - * @param array $iconProps An optional array that holds icon properties. - * - * @return HTMLNode - */ - public function createButton($props = [], $text = null, $icon = null, $iconProps = []) { - $btn = new HTMLNode('v-btn', $props); - - if ($text !== null) { - $btn->text($text); - } - - if ($icon !== null) { - $btn->addChild('v-icon', $iconProps, false)->text($icon); - } - - return $btn; - } - /** - * Creates a basic v-data-table with the ability to search. - * - * @param string $searchLabel A string that represents search label. - * - * @param string $searchModel The name of the model that represents search value. - * - * @param array $attrs An array of attributes for the datatable. - * - * @return HTMLNode - */ - public function createDataTable($searchLabel = 'Search', $searchModel = 'search', array $attrs = []) { - $table = new HTMLNode('v-data-table'); - $searchArea = new HTMLNode('template', [ - 'v-slot:top' - ]); - $searchArea->addChild('v-text-field', [ - 'v-model' => $searchModel, - 'label' => $searchLabel, - 'class' => "mx-4", - 'append-icon' => "mdi-magnify" - ]); - $attrs[':search'] = $searchModel; - $table->addChild($searchArea); - $table->setAttributes($attrs); - - return $table; - } - /** - * Creates a v-autocomplete element that represents a select. - * @param string $items The name of the model that represents the - * items to select from. - * - * @param string $label A label for the input element. - * - * @param array $extraAttrs An optional array of extra attributes for - * the select. - * - * @return HTMLNode - */ - public function createSelect($items, $label, array $extraAttrs) { - $select = new HTMLNode('v-autocomplete'); - - if ($items !== null) { - $select->setAttribute(':items', $items); - } - $select->setAttribute('label', $label); - $select->setAttributes($extraAttrs); - - return $select; - } - /** - * Creates a basic date picker input element. - * - * @param string $menuModel The name of the model which is used to - * represents the menu of the input. - * - * @param array $attrs An associative array that holds extra attributes - * for the date picker input. - * - * @return HTMLNode - */ - public function datePicker($menuModel = 'menu', $attrs = []) { - $dateModel = isset($attrs['v-model']) ? $attrs['v-model'] : 'date'; - - $node = new HTMLNode('v-menu', [ - 'ref' => "$menuModel", - 'v-model' => "$menuModel", - ':close-on-content-click' => "false", - 'transition' => "scale-transition", - 'offset-y', - 'min-width' => "290px", - ]); - $attrs[] = 'no-title'; - $attrs[] = 'scrollable'; - $attrs['color'] = 'green lighten-1'; - - $attrs['v-model'] = $dateModel; - - $label = isset($attrs['label']) ? $attrs['label'] : 'Select a date.'; - $disabled = in_array('disabled', $attrs) ? 'disabled' : ''; - $node->addChild('template ', [ - 'v-slot:activator' => "{ on, attrs }" - ], false)->addChild('v-text-field', [ - 'v-model' => "$dateModel", - 'label' => "$label", - 'prepend-icon' => "mdi-calendar", - 'readonly', - 'clearable', - 'v-bind' => "attrs", - 'v-on' => "on", - $disabled - ]); - - if (isset($attrs['@input'])) { - $node->getLastChild()->getLastChild()->setAttribute('@input', $attrs['@input']); - $attrs['@change'] = $attrs['@input']; - unset($attrs['@input']); - } - - if (isset($attrs[':loading'])) { - $node->getLastChild()->getLastChild()->setAttribute(':loading', $attrs[':loading']); - unset($attrs[':loading']); - } - $attrs['@input'] = "$menuModel = false"; - $node->addChild('v-date-picker', $attrs); - - return $node; - } - /** - * Returns an object of type Json that contains all JSON attributes. - * - * Initially, the object will contain all common attributes for all pages. - * - * @return Json - * - */ - public function getJson() { - return $this->jsonData; - } - /** - * Returns the object that holds the inline JavaScript code. - * - * @return JsCode - */ - public function getTopInlineJs() { - return $this->topInlineJs; - } - public function isDark() { - return $this->isDark; - } - /** - * Sets the JavaScript file which will be used to initialize vue. - * - * @param string $jsFilePath A string that represents the path of the - * file such as 'assets/js/init-vue.js'. - * - */ - public function setVueJs($jsFilePath) { - $this->addBeforeRender(function (WebPage $page, $jsPath) - { - $page->removeChild('vue-script'); - $page->getDocument()->addChild('script', [ - 'type' => 'text/javascript', - 'src' => $jsPath.'?jv='.WebFioriApp::getAppConfig()->getVersion(), - 'id' => 'vue-script' - ]); - }, [$jsFilePath]); - } - private function _checkIsDark() { - $darkArg = Request::getParam('dark'); - - if ($darkArg !== null) { - $darkArg = $darkArg == 't' ? true : false; - } else { - $darkArg = SessionsManager::get('dark'); - - if ($darkArg === null) { - $darkArg = true; - } - } - $this->isDark = $darkArg; - SessionsManager::set('dark', $darkArg); - $this->addToJson([ - 'dark' => $darkArg - ]); - } -} diff --git a/themes/ibrahim/IbrahimTheme.php b/themes/ibrahim/IbrahimTheme.php deleted file mode 100644 index b8523cd..0000000 --- a/themes/ibrahim/IbrahimTheme.php +++ /dev/null @@ -1,504 +0,0 @@ -setDescription('A theme which was built for the website https://ibrahim-binalshikh.me ' - .'using Vue, Vuetify and WebFiori framework.'); - $this->setLicenseName('MIT Licesnse'); - $this->setVersion('1.0'); - - $this->setAfterLoaded(function (IbrahimTheme $theme) - { - $page = $theme->getPage(); - $page->addBeforeRender(function (WebPage $page, IbrahimTheme $theme) - { - $gta = $theme->getGtag(); - - if ($gta !== null) { - $theme->getPage()->getDocument()->getBody()->insert($gta, 0); - } - - $appDiv = new HTMLNode('div', [ - 'id' => 'app' - ]); - $vApp = new HTMLNode('v-app'); - $appDiv->addChild($vApp); - $appDiv->addChild($appDiv); - $body = $page->getChildByID('page-body'); - $body->setNodeName('v-main'); - - $header = $page->getChildByID('page-header'); - $footer = $page->getChildByID('page-footer'); - $vApp->addChild($header); - $vApp->addChild($body); - $sideMenu = $body->getChildByID('side-content-area'); - $body->removeChild($sideMenu); - $vApp->addChild($sideMenu); - $vApp->addChild($footer); - $page->getDocument()->removeChild($header); - $page->getDocument()->removeChild($body); - $page->getDocument()->removeChild($footer); - $page->getDocument()->addChild($appDiv); - $page->getDocument()->getChildByID('main-content-area')->setClassName('container'); - }, [$theme]); - $page->addBeforeRender(function (WebPage $page) - { - $page->getDocument()->getBody()->addChild('script', [ - 'type' => 'text/javascript', - 'src' => 'assets/ibrahim/default.js', - 'id' => 'vue-script' - ]); - }); - $page->addBeforeRender(function (WebPage $p) - { - if (!($p instanceof BasePage)) { - $darkArg = Request::getParam('dark'); - - if ($darkArg !== null) { - $darkArg = $darkArg == 't' ? true : false; - } else { - $darkArg = SessionsManager::get('dark'); - - if ($darkArg === null) { - $darkArg = true; - } - } - $this->isDark = $darkArg; - SessionsManager::set('dark', $darkArg); - $jsonData = new Json([ - 'rtl' => $p->getTranslation()->getWritingDir() == 'rtl', - 'dark' => $darkArg, - 'darkTheme' => new Json([ - 'primary' => '#8bc34a', - 'secondary' => '#4caf50', - 'accent' => '#795548', - 'error' => '#f44336', - 'warning' => '#ff9800', - 'info' => '#607d8b', - 'success' => '#00bcd4' - ]), - 'lightTheme' => new Json([ - 'primary' => '#8bc34a', - 'secondary' => '#4caf50', - 'accent' => '#795548', - 'error' => '#f44336', - 'warning' => '#ff9800', - 'info' => '#607d8b', - 'success' => '#00bcd4' - ]) - ]); - $inlineJs = new JsCode(); - $inlineJs->addCode('window.data = '.$jsonData.';'); - $p->getDocument()->getHeadNode()->addChild($inlineJs); - } - }); - }); - } - public function createAvatar() { - $vList = new HTMLNode('v-list'); - $vList->addChild('v-list-item') - ->addChild('v-list-item-avatar') - ->addChild('img', [ - 'src' => 'assets/images/WFLogo512.png', - 'alt' => 'A' - ]); - - return $vList; - } - - public function createHTMLNode($options = []) { - $type = isset($options['name']) ? $options['name'] : 'div'; - - if ($type == 'heading') { - return $this->createHeading($options); - } else { - if ($type == 'menu') { - $text = isset($options['title']) ? $options['title'] : 'Menu'; - $attrs = [ - 'bottom', - 'origin' => "center center", - 'transition' => "scale-transition", - 'color' => "transparent" - ]; - - return $this->createMenu($text, $attrs); - } else { - if ($type == 'expansion-panel') { - $panel = new HTMLNode('v-expansion-panel'); - $text = isset($options['heading']) ? $options['heading'] : 'Item'; - $panel->addChild('v-expansion-panel-header', [], false)->text($text); - $panel->addChild('v-expansion-panel-content'); - - return $panel; - } else { - if ($type == 'title') { - $title = isset($options['title']) ? $options['title'] : $this->getPage()->getTitle(); - - return $this->createPageTitle($title); - } else { - if ($type == 'select') { - $select = new HTMLNode('v-autocomplete'); - $items = isset($options['items']) ? $options['items'] : null; - - if ($items !== null) { - $select->setAttribute(':items', $items); - } - $label = isset($options['label']) ? $options['label'] : 'Select an option.'; - $select->setAttribute('label', $label); - - return $select; - } else { - if ($type == 'share-button') { - return $this->createShareButton(); - } else { - return parent::createHTMLNode($options); - } - } - } - } - } - } - } - - - public function getAsideNode() { - if ($this->getPage()->getLangCode() == 'AR') { - $right = 'right'; - } else { - $right = ''; - } - $sideDrawer = new HTMLNode('v-navigation-drawer', [ - 'v-model' => "drawer", - 'app', $right, - 'width' => '250px', - 'app', 'temporary', - ]); - $sideDrawer->addChild($this->createAvatar()); - $sideDrawer->addChild('v-divider'); - $itemsPanel = new HTMLNode('template'); - $sideDrawer->addChild($itemsPanel); - $itemsPanel->addChild('v-expansion-panels', [], false) - ->addChild($this->createDrawerMenuItem($this->createButton(['text', 'block', 'href' => $this->getBaseURL().'/about-me'], Page::translation()->get('main-menu/about-me'), 'mdi-information-variant'))) - ->addChild($this->createDrawerMenuItem($this->createButton(['text', 'block', 'href' => $this->getBaseURL().'/contact-me'], Page::translation()->get('main-menu/contact-me'), 'mdi-comment-plus-outline'))); - - return $sideDrawer; - } - public function getFooterNode() { - $footer = new HTMLNode('v-footer', [ - 'padless' - ]); - $card = new HTMLNode('v-card', ['flat', 'tile', 'class' => 'flex', 'dark']); - $footer->addChild($card); - $card->addChild('v-card-text') - ->addChild($this->createButton([ - 'text', - 'fab', - 'x-small', - 'target' => '_blank', - 'href' => 'https://www.linkedin.com/in/ibrahim-binalshikh/'], null, 'mdi-linkedin'), true) - ->addChild($this->createButton([ - 'text', - 'fab', - 'x-small', - 'target' => '_blank', - 'href' => 'https://t.me/WarriorVx'], null, 'mdi-telegram'), true) - ->addChild($this->createButton([ - 'text', - 'fab', - 'x-small', - 'target' => '_blank', - 'href' => 'https://github.com/usernane'], null, 'mdi-github'), true); - - - $card->addChild('v-card-text') - ->addChild('small') - ->text($this->getPage()->get('footer/built-with')) - ->addChild(new Anchor('https://webfiori.com', $this->getPage()->get('general/framework-name'))); - - $card->addChild('v-divider') - ->addChild('v-card-text', ['flat'], false) - ->addChild('small', [], false)->text($this->getPage()->get('footer/all-rights').' '.date('Y')); - - return $footer; - } - - public function getGtag() { - if (defined('G_TAG')) { - $node = new HTMLNode('noscript'); - $node->addChild('iframe', [ - 'src' => "https://www.googletagmanager.com/ns.html?id=".G_TAG, - 'height' => "0", - 'width' => "0", - 'style' => "display:none;visibility:hidden" - ]); - - return $node; - } - } - - public function getHeadNode() { - $head = new HeadNode(); - $head->addJs('https://unpkg.com/vue@2.x.x'); - $head->addCSS('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900'); - $head->addCSS('https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css'); - $head->addCSS('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css'); - $head->addJs('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js'); - $head->addJs('https://cdn.jsdelivr.net/gh/usernane/AJAXRequestJs@1.x.x/AJAXRequest.js',[ - 'revision' => true - ]); - - if (defined('RECAPTCHA_SITE_KEY')) { - $head->addJs('https://www.google.com/recaptcha/api.js?render='.RECAPTCHA_SITE_KEY); - } - - if (defined('G_TAG')) { - $head->addJs('https://www.googletagmanager.com/gtag/js?id='.G_TAG, [ - 'async' - ]); - $head->addChild('script', [ - 'type' => 'text/javascript' - ], false)->text("window.dataLayer = window.dataLayer || [];" - ."function gtag(){" - ."dataLayer.push(arguments);" - ."}" - ."gtag('js', new Date());" - ."gtag('config', '".GTA."');"); - } - - return $head; - } - - public function getHeaderNode() { - $vAppBar = new HTMLNode('v-app-bar', [ - 'app', - 'color' => 'green', - //'src' => $this->getBaseURL().'/assets/images/WFLogo512.png', - //'hide-on-scroll', - 'elevate-on-scroll', - 'fixed', - 'perminant' - ]); - - $vAppBar->addChild('v-app-bar-nav-icon', [ - 'class' => 'd-sm-flex d-md-none', - '@click' => "drawer = !drawer", - ], true)->addChild('v-toolbar-title', [ - 'style' => [ - 'min-width' => '250px' - ] - ]) - ->addChild('v-row',[ - 'class' => 'd-none d-md-flex' - ]) - ->addChild('v-col', [ - 'cols' => 12, - 'md' => 4 - ])->addChild('img', [ - 'src' => 'assets/images/WFLogo512.png', - 'style' => [ - 'width' => '60px' - ] - ], true) - ->getParent() - ->addChild('v-col', [ - 'cols' => 12, - 'md' => 8, - 'class' => 'align-center d-flex' - ]) - ->addChild(new Anchor($this->getBaseURL(), - $this->getPage()->getWebsiteName() - ), [ - 'style' => [ - 'color' => 'white', - 'text-decoration' => 'none', - 'font-weight' => 'bold' - ], - 'class' => 'site-name align-center' - ]); - $vAppBar->addChild('v-spacer'); - $navLinksContainer = new HTMLNode('v-container', [ - 'class' => 'd-none d-md-flex' - ]); - $vAppBar->addChild($navLinksContainer); - $navLinksContainer - ->addChild($this->createButton(['text', 'href' => $this->getBaseURL().'/about-me'], $this->getPage()->get('main-menu/about-me'), 'mdi-information-variant'), true) - ->addChild($this->createButton(['text', 'href' => $this->getBaseURL().'/contact-me'], $this->getPage()->get('main-menu/contact-me'), 'mdi-comment-plus-outline'), true) - ->getParent()->addChild('v-spacer'); - //$this->createDarkSwitch($vAppBar); - $this->createLangSwitch($vAppBar); - - return $vAppBar; - } - private function createButton($props = [], $text = null, $icon = null, $iconProps = []) { - $btn = new HTMLNode('v-btn', $props); - - if ($text !== null) { - $btn->text($text); - } - - if ($icon !== null) { - if (isset($iconProps['style'])) { - $iconProps['style']['margin'] = '8px'; - } else { - $iconProps['style'] = [ - 'margin' => '5px' - ]; - } - $btn->addChild('v-icon', $iconProps, false)->text($icon); - } - - return $btn; - } - private function createDarkSwitch($vAppBar) { - $vAppBar->addChild('v-icon', [ - 'v-if' => '$vuetify.theme.dark', - '@click' => '$vuetify.theme.dark = !$vuetify.theme.dark' - ], false)->text('mdi-lightbulb-on'); - $vAppBar->addChild('v-icon', [ - 'v-if' => '!$vuetify.theme.dark', - '@click' => '$vuetify.theme.dark = !$vuetify.theme.dark' - ], false)->text('mdi-lightbulb-outline'); - } - private function createDrawerMenuItem($listTitle) { - $item = new HTMLNode('v-list-item'); - $last = $item->addChild('v-list-item-content', [], false) - ->addChild('v-list-item-title', [], false); - - if ($listTitle instanceof HTMLNode) { - $last->addChild($listTitle); - } else { - $last->text($listTitle); - } - - return $item; - } - private function createHeading($options) { - $headingLvl = $this->getHeadingLevel($options); - $headingContainer = new HTMLNode('v-row'); - $heading = new HTMLNode('h'.$headingLvl); - - if (isset($options['id'])) { - $heading->setID($options['id']); - } - - if (isset($options['title'])) { - if ($options['title'] instanceof HTMLNode) { - $heading->addChild($options['title']); - } else { - $heading->text($options['title']); - } - } - $headingCol = new HTMLNode('v-col', [ - 'cols' => 10 - ]); - $headingContainer->addChild($headingCol); - $headingCol->addChild($heading); - - return $headingContainer; - } - private function createLangSwitch($vAppBar) { - $switchLangMenu = new HTMLNode('v-menu', [ - 'bottom', - 'origin' => "center center", - 'transition' => "slide-y-transition", - 'open-on-hover' - ]); - $vAppBar->addChild($switchLangMenu); - $switchLangMenu->addChild('template', [ - 'v-slot:activator' => "{ on, attrs }" - ], false)->addChild($this->createButton([ - 'fab', - 'text', - 'v-bind' => "attrs", - 'v-on' => "on" - ], null, 'mdi-earth')); - $langsList = new HTMLNode('v-list'); - $switchLangMenu->addChild($langsList); - $canonical = explode('?', $this->getPage()->getCanonical())[0]; - - foreach ($this->getPage()->get('main-menu/lang-switch') as $langCode => $label) { - $langsList->addChild('v-list-item', [], false) - ->addChild('v-list-item-title', [], false) - ->addChild(new Anchor($canonical.'?lang='.$langCode, $label)); - } - } - private function createMenu($title, $attrs) { - $menu = new HTMLNode('v-menu', $attrs); - $menu->addChild('template', [ - 'v-slot:activator' => "{ on, attrs }" - ], false)->addChild('v-btn', [], false) - ->text($title); - - return $menu; - } - private function createPageTitle($title) { - $row = new HTMLNode('v-row', []); - $row->addChild('v-col', [ - 'cols' => 12 - ], false)->addChild('v-card', [], false) - ->addChild('v-card-title', [], false)->text($title); - - return $row; - } - private function createShareButton() { - $dir = $this->getPage()->getWritingDir() == 'ltr' ? 'right' : 'left'; - $btn = new HTMLNode('v-speed-dial', [ - 'v-model' => "fab", - 'transition' => 'slide-y-reverse-transition', - 'buttom', $dir, 'bottom', 'fixed' - ]); - $btn->addChild('template ', [ - 'v-slot:activator' - ], false)->addChild('v-btn', [ - 'fab', 'v-model' => "fab" - ], false)->addChild('v-icon', [ - 'v-if' => '!fab' - ], false)->text('mdi-share-variant-outline') - ->getParent()->addChild('v-icon', [ - 'v-else' - ], false)->text('mdi-close'); - $btn->addChild($this->createButton([ - 'fab', - 'dark', - 'small', - 'color' => "green" - ], null, 'mdi-pencil')); - $btn->addChild($this->createButton([ - 'fab', - 'dark', - 'small', - 'color' => "red" - ], null, 'mdi-delete')); - - return $btn; - } - private function getHeadingLevel($options) { - if (isset($options['level'])) { - $asInt = intval($options['level']); - - if ($asInt > 0 && $asInt < 7) { - return $asInt; - } - } - - return 1; - } -} - -return __NAMESPACE__; diff --git a/themes/newFiori/NewFiori.php b/themes/newFiori/NewFiori.php deleted file mode 100644 index 04aee73..0000000 --- a/themes/newFiori/NewFiori.php +++ /dev/null @@ -1,389 +0,0 @@ -setVersion('1.0'); - $this->setLicenseName('MIT'); - $this->setDescription('The new WebFiori framework website theme.'); - - $this->setAfterLoaded(function (Theme $theme) { - $page = $theme->getPage(); - $appDiv = new HTMLNode('div', [ - 'id' => 'app' - ]); - $vApp = new HTMLNode('v-app'); - $appDiv->addChild($vApp); - $appDiv->addChild($appDiv); - $body = $page->getChildByID('page-body'); - $body->setNodeName('v-main'); - - $header = $page->getChildByID('page-header'); - $footer = $page->getChildByID('page-footer'); - $vApp->addChild($header); - $vApp->addChild($body); - $sideMenu = $body->getChildByID('side-content-area'); - $body->removeChild($sideMenu); - $vApp->addChild($sideMenu); - $vApp->addChild($footer); - $page->removeChild($header); - $page->removeChild($body); - $page->removeChild($footer); - $page->getDocument()->addChild($appDiv); - $page->getChildByID('main-content-area')->setClassName('container'); - $page->addBeforeRender(function (WebPage $page) { - $page->getDocument()->getBody()->addChild('script', [ - 'type' => 'text/javascript', - 'src' => 'assets/newFiori/default.js', - 'id' => 'default-vue-init' - ]); - $page->getDocument()->getBody()->addChild('script', [ - 'src' => 'assets/js/prism.js', - 'type' => 'text/javascript' - ], false); - $page->getDocument()->getBody()->addChild('script', [ - 'src' => 'assets/js/algolia.js', - 'type' => 'text/javascript' - ], false); - }); - }); - } - public function getAsideNode() { - $page = $this->getPage(); - $right = $page->getWritingDir() == 'rtl' ? 'right' : ''; - $sideDrawer = new HTMLNode('v-navigation-drawer', [ - 'v-model' => "drawer", - 'app', $right, - 'width' => '250px', - 'app', 'temporary', - ]); - $sideDrawer->addChild('v-divider'); - $itemsPanel = new HTMLNode('template'); - $sideDrawer->addChild($itemsPanel); - $itemsPanel->addChild('v-expansion-panels', [], false) - ->addChild($this->createDrawerMenuItem( - $this->createButton([ - 'text', 'block', - 'href' => $this->getBaseURL().'/learn' - ], 'Learn', 'mdi-information-variant')), true) - ->addChild($this->createDrawerMenuItem( - $this->createButton([ - 'text', 'block', - 'href' => $this->getBaseURL().'/docs/webfiori' - ], 'API Reference', 'mdi-information-variant')), true) - ->addChild($this->createDrawerMenuItem( - $this->createButton([ - 'text', 'block', - 'href' => $this->getBaseURL().'/download' - ], 'Download', 'mdi-information-variant')), true) - ->addChild($this->createDrawerMenuItem( - $this->createButton([ - 'text', 'block', - 'href' => $this->getBaseURL().'/contribute' - ], 'Contribute', 'mdi-information-variant')), true) - ; - return $sideDrawer; - } - - public function getFooterNode() { - $page = $this->getPage(); - $footer = new HTMLNode('v-footer', [ - 'padless', - ]); - $card = new HTMLNode('v-card', [ - 'flat', 'tile', 'class' => 'flex text-center', 'dark']); - $footer->addChild($card); -// $card->addChild('v-card-text') -// ->addChild($this->createButton([ -// 'text', -// 'fab', -// 'x-small', -// 'target' => '_blank', -// 'href' => 'https://www.linkedin.com/in/ibrahim-binalshikh/'], null, 'mdi-linkedin'), true) -// ->addChild($this->createButton([ -// 'text', -// 'fab', -// 'x-small', -// 'target' => '_blank', -// 'href' => 'https://t.me/WarriorVx'], null, 'mdi-telegram'), true) -// ->addChild($this->createButton([ -// 'text', -// 'fab', -// 'x-small', -// 'target' => '_blank', -// 'href' => 'https://github.com/usernane'], null, 'mdi-github'), true); -// - // - $card->addChild('v-card-text') - ->addChild('small') - ->text($page->get('footer/built-with')) - ->addChild(new Anchor('https://webfiori.com', $page->get('general/framework-name')), true) - ->text(', ') - ->addChild(new Anchor('https://vuejs.org', 'Vue'), true) - ->text(' and ') - ->addChild(new Anchor('https://vuetifyjs.com', 'Vuetify'), true); - - $card->addChild('v-divider', true) - ->addChild('v-card-text', ['flat']) - ->addChild('small')->text('All Rights Reserved'.' © 2018 - '.date('Y')); - return $footer; - } - - public function getHeadNode() { - $head = new HeadNode(); - $head->addCSS('assets/css/prism.css'); - $head->addCSS('assets/css/code-theme.css'); - - //$head->addCSS('https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css'); - $head->addJs("https://cdn.jsdelivr.net/npm/algoliasearch@4.5.1/dist/algoliasearch-lite.umd.js"); - //$head->addJs('https://cdn.jsdelivr.net/npm/instantsearch.js@4'); - - $head->addJs('https://unpkg.com/vue@2.x.x'); - $head->addCSS('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900'); - $head->addCSS('https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css'); - $head->addCSS('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css'); - $head->addJs('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js'); - $head->addJs('https://cdn.jsdelivr.net/gh/usernane/AJAXRequestJs@1.x.x/AJAXRequest.js',[ - 'revision' => true - ]); - - - $head->addJs("https://www.googletagmanager.com/gtag/js?id=UA-91825602-2", ['async'=>''], false); - $jsCode = new JsCode(); - $jsCode->addCode("window.dataLayer = window.dataLayer || []; - function gtag(){dataLayer.push(arguments);} - gtag('js', new Date()); - - gtag('config', 'UA-91825602-2');"); - $head->addChild($jsCode); - return $head; - } - - public function getHeaderNode() { - $page = $this->getPage(); - - $vAppBar = new HTMLNode('v-app-bar', [ - 'app', - 'color' => '#d2ed9a', - //'src' => $this->getBaseURL().'/assets/images/WFLogo512.png', - //'hide-on-scroll', - //'elevate-on-scroll', - 'fixed', - 'height' => '50px', - 'flat', - 'dense' - ]); - - $vAppBar->addChild('v-app-bar-nav-icon', [ - 'class' => 'd-sm-flex d-md-none', - '@click' => "drawer = !drawer", - ], true); - //Add Title with logo - $vAppBar->addChild('v-toolbar-title', [ - 'class' => 'd-none d-md-flex', - 'style' => [ - 'min-width' => '250px' - ] - ]) - ->addChild('v-row',[ - 'class' => 'd-none d-md-flex' - ]) - ->addChild('v-col', [ - 'cols' => 12, - 'md' => 4 - ])->addChild('img', [ - 'src' => 'assets/images/WFLogo512.png', - 'style' => [ - 'width' => '45px' - ] - ], true)->getParent() - ->addChild('v-col', [ - 'cols' => 12, - 'md' => 8, - 'class' => 'align-center d-flex' - ]) - ->addChild(new Anchor($this->getBaseURL(), - $page->getWebsiteName() - ), [ - 'style' => [ - 'color' => 'black', - 'text-decoration' => 'none', - 'font-weight' => 'bold' - ], - 'class' => 'site-name align-center' - ]); - $vAppBar->addChild('v-spacer'); - $navLinksContainer = new HTMLNode('v-container', [ - 'class' => 'd-none d-md-flex' - ]); - $vAppBar->addChild($navLinksContainer); - $navLinksContainer->addChild( - self::createButton(['text', - 'href' => $this->getBaseURL().'/docs/webfiori'], 'API Reference'), true) - ->addChild(self::createButton(['text', 'href' => $this->getBaseURL().'/learn'], 'Learn'), true) - ->addChild(self::createButton(['text', 'href' => $this->getBaseURL().'/download'], 'Download'), true) - ->addChild(self::createButton(['text', 'href' => $this->getBaseURL().'/contribute'], 'Contribute'), true) - ->getParent()->addChild('v-spacer'); - - $vAppBar->addChild($this->createTopSearchBar()); - $vAppBar->addChild('v-spacer'); - $homeImgContainer = $vAppBar->addChild('div', [ - 'class' => 'd-sm-flex d-md-none align-center', - ]); - $homeImgContainer->addChild('a', [ - 'href' => \webfiori\framework\WebFioriApp::getAppConfig()->getHomePage() - ])->img([ - 'src' => 'assets/images/WFLogo512.png', - 'style' => [ - 'width' => '45px' - ] - ]); - return $vAppBar; - } - private function createTopSearchBar() { - $searchContainer = new HTMLNode('v-container', [ - 'class' => 'd-flex align-center d-none d-md-flex' - ]); - - $row = $searchContainer->addChild('v-row', [ - 'no-gutters' - ]); - - $vList = $row->addChild('v-col', [ - 'cols' => 12, - 'no-gutters', - - ])->addChild('v-menu', [ - 'relative','overflow', - 'v-model'=>"show_search_menu", - 'offset-y', - 'bottom' - ])->addChild('template', [ - 'v-slot:activator'=>"{ on, attrs }", - - ]) - ->addChild('v-text-field', [ - 'outlined', 'prepend-inner-icon' => 'mdi-magnify', - 'dense', 'rounded', 'hide-details', - 'id' => 'search-box', - 'v-model' => 'search_val','@input' => 'search', - 'v-bind'=>"attrs", - 'v-on'=>"on" - ], true)->getParent() - ->addChild('v-list'); - - $vList->addChild('v-subheader', [ - 'style' => 'font-weight: bold;' - ]) - ->text('Learn') - ->getParent() - ->addChild('v-list-item', [ - 'v-for' => 'result in docs_search_results' - ])->addChild('v-list-item-title', [], false) - ->addChild('a', [ - ':href' => 'result.link', - 'style' => [ - 'font-size' => '9pt', - 'font-weight' => 'bold' - ] - ])->addChild('span', [ - 'v-if' => 'result.parent_page !== null' - ])->text('{{result.parent_page}} > {{result.title}}') - ->getParent() - ->addChild('span', [ - 'v-else' => 'result.parent_page' - ])->text('{{result.title}}'); - - $vList->addChild('v-subheader', [ - 'style' => 'font-weight: bold;' - ]) - ->text('Classes') - ->getParent() - ->addChild('v-list-item', [ - 'v-for' => 'result in search_results' - ])->addChild('v-list-item-title', [], false) - ->addChild('a', [ - ':href' => 'result.link', - 'style' => [ - 'font-size' => '9pt', - 'font-weight' => 'bold' - ] - ])->text('{{result.class_name}}') - ->getParent() - ->addChild('v-list-item-subtitle',[ - 'style' => [ - 'font-size' => '9pt' - ] - ]) - ->text('{{result.summary}}'); - $vList->addChild('v-subheader', [ - 'style' => 'font-weight: bold;' - ]) - ->text('Methods') - ->getParent() - ->addChild('v-list-item', [ - 'v-for' => 'result in methods_search_results' - ])->addChild('v-list-item-title') - ->addChild('a', [ - ':href' => 'result.link', - 'style' => [ - 'font-size' => '9pt', - 'font-weight' => 'bold' - ] - ])->text('{{result.name}}') - ->getParent() - ->addChild('v-list-item-subtitle',[ - 'style' => [ - 'font-size' => '9pt' - ] - ]) - ->text('{{result.summary}}') - ->getParent()->getParent()->getParent() - ->addChild('a', [ - 'href' => 'https://www.algolia.com/', - 'target' => '_blank', - 'class' => 'd-flex', - 'style' => 'border-top: 1px solid;' - ]) - ->img([ - 'src' => 'assets/images/search-by-algolia-light-background.webp', - 'style'=> ['width' => '130px'] - ]); - return $searchContainer; - } - public static function createButton($props = [], $text = null, $icon = null, $iconProps = []) { - $btn = new HTMLNode('v-btn', $props); - - if ($text !== null) { - $btn->text($text); - } - if ($icon !== null) { - $btn->addChild('v-icon', $iconProps, false)->text($icon); - } - return $btn; - } - public function createDrawerMenuItem($listTitle) { - $item = new HTMLNode('v-list-item'); - $last = $item->addChild('v-list-item-content') - ->addChild('v-list-item-title'); - if ($listTitle instanceof HTMLNode) { - $last->addChild($listTitle); - } else { - $last->text($listTitle); - } - return $item; - } -} -return __NAMESPACE__; diff --git a/themes/template/TemplateTheme.php b/themes/template/TemplateTheme.php deleted file mode 100644 index 1d0694a..0000000 --- a/themes/template/TemplateTheme.php +++ /dev/null @@ -1,77 +0,0 @@ -setAuthor('Ibrahim Ali'); - $this->setAuthorUrl('http://ibrahim-2017.blogspot.com'); - $this->setName('Template Theme'); - $this->setVersion('1.0'); - $this->setDescription('Generic Theme Template.'); - $this->setImagesDirName('images'); - $this->setJsDirName('js'); - $this->setCssDirName('css'); - $this->addComponents([ - ]); - $this->setBeforeLoaded(function() - { - //the code in here will be executed before the theme is loaded. - //You cannot change page layout here. - //But you can use it to initialize any variables your theme is using - }); - $this->setAfterLoaded(function() - { - //the code in here will be executed after the theme is loaded. - //You can change page layout here. - }); - } - /** - * Create your custom HTML nodes here. - * @param type $options - * @return HTMLNode - */ - public function createHTMLNode($options = []) { - $node = new HTMLNode(); - - return $node; - } - - public function getAsideNode() { - $menu = new HTMLNode('div'); - $menu->addTextNode('Aside'); - - return $menu; - } - - public function getFooterNode() { - $node = new HTMLNode('div'); - $fNode = new HTMLNode('footer'); - $fNode->addTextNode('Footer Section'); - $node->addChild($fNode); - - return $node; - } - - public function getHeadNode() { - $headTag = new HeadNode(); - //Add head tag tags here as needed. - //Note that you don't have to add CSS and JS files of the theme as - //They will be added automatically for you. - - return $headTag; - } - - public function getHeaderNode() { - $headerSec = new HTMLNode(); - $headerBody = new HTMLNode(); - $headerBody->addTextNode('Header Sec'); - $headerSec->addChild($headerBody); - - return $headerSec; - } -} diff --git a/themes/vuetify-based/LangExt.php b/themes/vuetify-based/LangExt.php deleted file mode 100644 index 5a97ebc..0000000 --- a/themes/vuetify-based/LangExt.php +++ /dev/null @@ -1,114 +0,0 @@ -getCode() == 'AR') { - $translation->createAndSet('vuetify', [ - 'noDataText' => 'لا توجد بيانات للعرض.', - 'sortBy' => 'ترتيب حسب', - 'close' => 'إغلاق' - ]); - $translation->createAndSet('vuetify/dataIterator', [ - 'pageText' => '{0}-{1} من {2}', - 'noResultsText' => 'لم يتم العثور على سجلات مطابقة.', - 'loadingText' => 'جاري تحميل العناصر...' - ]); - $translation->createAndSet('vuetify/dataTable', [ - 'itemsPerPageText' => 'عدد السطور لكل صفحة:' - ]); - $translation->createAndSet('vuetify/dataTable/ariaLabel', [ - 'sortDescending' => 'Sorted descending. Activate to remove sorting.', - 'sortAscending' => 'Sorted ascending. Activate to sort descending.', - 'sortNone' => 'Not sorted. Activate to sort ascending.' - ]); - $translation->createAndSet('vuetify/dataFooter', [ - 'pageText' => '{0}-{1} من {2}', - 'itemsPerPageText' => 'عدد العناصر بكل صفحة:', - 'itemsPerPageAll' => 'الجميع', - 'nextPage' => 'الصفحة التالية', - 'prevPage' => 'الصفحة السابقة', - 'firstPage' => 'الصفحة الأولى', - 'lastPage' => 'الصفحة الأخيرة' - ]); - $translation->createAndSet('datePicker', [ - 'itemsSelected' => 'تم تحديد {0}' - ]); - $translation->createAndSet('vuetify/carousel', [ - 'next' => 'الشكل التالي', - 'prev' => 'الشكل السابق' - ]); - $translation->createAndSet('vuetify/calendar', [ - 'moreEvents' => '{0} اكثر' - ]); - $translation->createAndSet('example/footer', [ - 'get-connected' => 'تواصل معنا عن طريق شبكات التواصل الإجتماعية!', - 'copyright-notice' => 'جميع الحقوق محفوظة © '.date('Y') - ]); - $translation->createAndSet('side-menu', [ - 'home' => 'الرئيسة', - 'account' => 'حسابي', - 'search' => 'بحث', - 'something-else' => 'شيء آخر' - ]); - } else { - $translation->createAndSet('vuetify', [ - 'noDataText' => 'No data available', - 'sortBy' => 'Sort by', - 'close' => 'Close' - ]); - $translation->createAndSet('vuetify/dataIterator', [ - 'pageText' => '{0}-{1} of {2}', - 'noResultsText' => 'No matching records found', - 'loadingText' => 'Loading items...' - ]); - $translation->createAndSet('vuetify/dataTable', [ - 'itemsPerPageText' => 'Rows per page:' - ]); - $translation->createAndSet('vuetify/dataTable/ariaLabel', [ - 'sortDescending' => 'Sorted descending. Activate to remove sorting.', - 'sortAscending' => 'Sorted ascending. Activate to sort descending.', - 'sortNone' => 'Not sorted. Activate to sort ascending.' - ]); - $translation->createAndSet('vuetify/dataFooter', [ - 'pageText' => '{0}-{1} of {2}', - 'itemsPerPageText' => 'Items per page:', - 'itemsPerPageAll' => 'All', - 'nextPage' => 'Next page', - 'prevPage' => 'Previous page', - 'firstPage' => 'First page', - 'lastPage' => 'Last page' - ]); - $translation->createAndSet('datePicker', [ - 'itemsSelected' => '{0} selected' - ]); - $translation->createAndSet('vuetify/carousel', [ - 'next' => 'Previous visual', - 'prev' => 'Next visual' - ]); - $translation->createAndSet('vuetify/calendar', [ - 'moreEvents' => '{0} more' - ]); - $translation->createAndSet('example/footer', [ - 'get-connected' => 'Stay in touch with us through social media!', - 'copyright-notice' => 'All Rights Reserved © '.date('Y') - ]); - $translation->createAndSet('side-menu', [ - 'home' => 'Home', - 'account' => 'My Account', - 'search' => 'Search', - 'something-else' => 'Something Else' - ]); - } - } -} diff --git a/themes/vuetify-based/VuetifyTheme.php b/themes/vuetify-based/VuetifyTheme.php deleted file mode 100644 index 31c4a30..0000000 --- a/themes/vuetify-based/VuetifyTheme.php +++ /dev/null @@ -1,279 +0,0 @@ -setVersion('1.0'); - $this->setAuthor('Ibrahim'); - $this->setLicenseName('MIT License'); - $this->setLicenseUrl('https://opensource.org/licenses/MIT'); - $this->setName('Vuetify Theme'); - $this->setJsDirName('js'); - $this->setImagesDirName('img'); - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - $page->includeI18nLables(true); - LangExt::extendLang($page->getTranslation()); - $topDiv = new HTMLNode('v-app'); - $topDiv->setID('app'); - $headerSec = $page->getChildByID('page-header'); - $page->getDocument()->removeChild($headerSec); - $bodySec = $page->getChildByID('page-body'); - $page->getDocument()->removeChild($bodySec); - $footerSec = $page->getChildByID('page-footer'); - $page->getDocument()->removeChild($footerSec); - $topDiv->addChild($footerSec)->addChild($headerSec)->addChild($bodySec); - $page->getDocument()->getBody()->addChild($topDiv); - $page->getDocument()->getChildByID('main-content-area')->setNodeName('v-main'); - $page->getDocument()->getChildByID('main-content-area')->setAttribute('app'); - }); - } - /** - * Creates a generic html node. - * The returned node will depends on the way the developer has implemented - * the method. - * @param array $options An associative array that contains options. - * @return HTMLNode - */ - public function createHTMLNode($options = []) { - $type = isset($options['type']) ? $options['type'] : 'div'; - - if ($type == 'v-list-item') { - $node = new HTMLNode('v-list-item'); - $icon = isset($options['icon']) ? $options['icon'] : null; - - if ($icon !== null) { - $iconNode = new HTMLNode('v-list-item-icon'); - $iconNode->addTextNode(''.$icon.'', false); - $node->addChild($iconNode); - } - $title = isset($options['title']) ? $options['title'] : null; - - if ($title !== null) { - $titleNode = new HTMLNode('v-list-item-title'); - $titleNode->addTextNode($title, false); - $node->addChild($titleNode); - } - - return $node; - } else { - if ($type == 'icon-button') { - $btn = new HTMLNode('v-btn'); - $btn->setAttribute('icon'); - $vIcon = new HTMLNode('v-icon'); - $btn->addChild($vIcon); - $icon = isset($options['icon']) ? $options['icon'] : 'mdi-information'; - $vIcon->addTextNode($icon); - - return $btn; - } - } - - return new HTMLNode(); - } - /** - * Creates the drawer which appears when menu button is clicked. - * @return HTMLNode - */ - public function getAsideNode() { - $node = new HTMLNode('v-navigation-drawer',[ - 'v-model' => 'drawer', - 'absolute',':right' => '$vuetify.rtl', - 'temporary','fixed' - ]); - $node->addChild('v-img',[ - 'src' => Page::imagesDir().'/side-nav.PNG', - ':aspect-ratio' => "16/9" - ], true)->addChild('v-row', [ - 'class' => 'lightbox white--text pa-2 fill-height', - 'align' => 'end' - ])->addChild('v-col') - ->addChild('div',['class' => 'subheading'])->text('Programming Academia') - ->getParent()->getParent()->getParent()->addChild('v-list', [ - 'dense','nav' - ])->addChild('v-list-item-group', [ - 'active-class' => 'deep-purple--text text--accent-4' - ])->addChild($this->createHTMLNode([ - 'type' => 'v-list-item', - 'title' => Page::translation()->get('side-menu/home'), - 'icon' => 'mdi-home' - ]))->addChild($this->createHTMLNode([ - 'type' => 'v-list-item', - 'title' => Page::translation()->get('side-menu/search'), - 'icon' => 'mdi-magnify' - ]))->addChild($this->createHTMLNode([ - 'type' => 'v-list-item', - 'title' => Page::translation()->get('side-menu/account'), - 'icon' => 'mdi-heart' - ]))->addChild($this->createHTMLNode([ - 'type' => 'v-list-item', - 'title' => Page::translation()->get('side-menu/something-else'), - 'icon' => 'mdi-information' - ])); - - return $node; - } - /** - * Creates the footer of the page. - * @return HTMLNode - */ - public function getFooterNode() { - $node = new HTMLNode(); - $app = new HTMLNode('v-footer'); - $app->setAttribute('app'); - $app->setAttributes(['dark','padless']); - $node->addChild($app); - - $vCard = new HTMLNode('v-card'); - $app->addChild($vCard); - $vCard->setAttributes([ - 'class' => 'flex', - 'flat','tile' - ]); - $vCardTitle = new HTMLNode('v-card-title'); - $vCardTitle->setClassName('teal social-media'); - $vCard->addChild($vCardTitle); - $vCardTitle->addTextNode(' - - - {{ icon }} - ', false); - $vCardText = new HTMLNode('v-card-text'); - $vCardText->setClassName('py-2 white--text text-center'); - - $copywriteNoticeNode = new HTMLNode('strong'); - $copywriteNoticeNode->addTextNode('All Rights Reserved'); - - - $poweredByNode = new HTMLNode('p'); - $poweredByNode->setClassName('footer-notice'); - $poweredByNode->addTextNode('Powered By: '); - $frameworkLink = new Anchor('https://webfiori.com', 'WebFiori Framework', '_blank'); - $poweredByNode->addChild($frameworkLink); - - - $vuetifyNode = new HTMLNode('p'); - $vuetifyNode->setClassName('footer-notice'); - $vuetifyNode->addTextNode('Theme Designed Using '); - $vuetifyLink = new Anchor('https://vuetifyjs.com', 'Vuetify', '_blank'); - $vuetifyNode->addChild($vuetifyLink); - - $vCardText->addChild($copywriteNoticeNode, true) - ->addChild($poweredByNode, true) - ->addChild($vuetifyNode); - - $vCard->addChild($vCardText); - - return $node; - } - /** - * Creates and returns the head node of the web page. - * It simply loads all needed JavaScript, CSS and any other resources. - * @return HeadNode - */ - public function getHeadNode() { - $node = new HeadNode(); - $lang = Page::translation(); - $json = new Json(); - $langVars = $lang->getLanguageVars(); - - foreach ($langVars as $key => $val) { - $json->add($key, $val,['array-as-object' => true]); - } - $node->addCSS('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900',[], false); - $node->addCSS('https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css', [], false); - $node->addCSS('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css', [], false); - $node->addJs('https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js', [], false); - $node->addJs('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js', [], false); - - return $node; - } - /** - * Creates the header section of the page and return it. - * @return HTMLNode - */ - public function getHeaderNode() { - $appBar = new HTMLNode('v-app-bar'); - $appBar->setAttributes([ - 'color' => 'red', - 'src' => 'https://picsum.photos/1920/1080?random', - 'hide-on-scroll', - 'elevate-on-scroll', - 'fixed','app' - ]); - - //Adds a small logo in the bar - $logo = new HTMLNode('v-img'); - $logo->setAttributes([ - 'src' => 'favicon.png', - 'max-height' => 45, - 'max-width' => 45 - ]); - - - //Adds a gradiant - - - //An icon to show and hide aside menu. - $drawerIcon = new HTMLNode('v-app-bar-nav-icon'); - - $drawerIcon->setAttribute('@click', 'drawer = true'); - - //Adds a text to the bar that represents website name - $titleNode = new HTMLNode('v-toolbar-title'); - $titleNode->addTextNode(Page::siteName()); - - $appBar->addChild('template', [ - 'v-slot:img' => "{ props }" - ])->addChild('v-img',[ - 'v-bind' => 'props', - 'gradient' => "to top right, rgba(19,84,122,.5), rgba(128,208,199,.8)" - ])->getParent()->getParent() - ->addChild($logo, true) - ->addChild($drawerIcon, true) - ->addChild($titleNode, true) - ->addChild('v-spacer', true) - - //Add extra actions to the bar such as search - ->addChild($this->createHTMLNode([ - 'type' => 'icon-button', - 'icon' => 'mdi-magnify' - ]), true) - ->addChild($this->createHTMLNode([ - 'type' => 'icon-button' - ]), true) - ->addChild($this->createHTMLNode([ - 'type' => 'icon-button', - 'icon' => 'mdi-heart' - ])); - - $node = new HTMLNode(); - $node->addChild($appBar); - - return $node; - } -} - -return __NAMESPACE__; diff --git a/themes/vuetify_emplate/VuetifyTemplate.php b/themes/vuetify_emplate/VuetifyTemplate.php deleted file mode 100644 index d09fdda..0000000 --- a/themes/vuetify_emplate/VuetifyTemplate.php +++ /dev/null @@ -1,101 +0,0 @@ -setName('Vuetify Template'); - $this->setAuthor('Ibrahim BinAlshikh'); - $this->setLicenseName('MIT'); - $this->setJsDirName('js'); - $this->setImagesDirName('img'); - - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - $page->includeI18nLables(true); - $page->addBeforeRender(function (WebPage $page) - { - $appDiv = new HTMLNode('div', [ - 'id' => 'app' - ]); - $vApp = new HTMLNode('v-app'); - $appDiv->addChild($vApp); - $appDiv->addChild($appDiv); - $body = $page->getChildByID('page-body'); - $body->setNodeName('v-main'); - - $header = $page->getChildByID('page-header'); - $footer = $page->getChildByID('page-footer'); - $vApp->addChild($header); - $vApp->addChild($body); - $sideMenu = $body->getChildByID('side-content-area'); - $body->removeChild($sideMenu); - $vApp->addChild($sideMenu); - $vApp->addChild($footer); - $page->getDocument()->removeChild($header); - $page->getDocument()->removeChild($body); - $page->getDocument()->removeChild($footer); - $page->getDocument()->addChild($appDiv); - $page->getDocument()->getChildByID('main-content-area')->setClassName('container'); - }, [$theme]); - $page->addBeforeRender(function (WebPage $page) - { - $page->getDocument()->getBody()->addChild('script', [ - 'type' => 'text/javascript', - 'src' => 'assets/vuetify-template/default.js', - 'id' => 'vue-script' - ]); - }); - }); - } - - public function createHTMLNode($options = []) { - return new HTMLNode(); - } - - public function getAsideNode() { - $aside = new HTMLNode('v-container'); - - return $aside; - } - - public function getFooterNode() { - $footer = new HTMLNode('v-footer'); - - return $footer; - } - - public function getHeadNode() { - $node = new HeadNode(); - $lang = Page::translation(); - - $node->addCSS(Page::cssDir().'/theme.css') - ->addCSS('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900',[], false) - ->addCSS('https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css', [], false) - ->addCSS('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css', [], false) - ->addJs('https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js', [], false) - ->addJs('https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js', [], false); - - return $node; - } - - public function getHeaderNode() { - $aside = new HTMLNode('v-toolbar'); - - return $aside; - } -} - -return __NAMESPACE__; diff --git a/themes/webfiori/LangExt.php b/themes/webfiori/LangExt.php deleted file mode 100644 index ebd26dc..0000000 --- a/themes/webfiori/LangExt.php +++ /dev/null @@ -1,35 +0,0 @@ -createDirectory('menus/main-menu'); - $langCode = $trans->getCode(); - - if ($langCode == 'AR') { - $trans->setMultiple('menus/main-menu', [ - 'menu-item-1' => 'عنصر قائمة 1', - 'menu-item-2' => 'عنصر قائمة 2', - 'menu-item-3' => 'عنصر قائمة 3', - 'menu-item-4' => 'عنصر قائمة 4' - ]); - } else { - $trans->setMultiple('menus/main-menu', [ - 'menu-item-1' => 'Menu Item 1', - 'menu-item-2' => 'Menu Item 2', - 'menu-item-3' => 'Menu Item 3', - 'menu-item-4' => 'Menu Item 4' - ]); - } - } -} diff --git a/themes/webfiori/WebFioriTheme.php b/themes/webfiori/WebFioriTheme.php deleted file mode 100644 index 6fb6f91..0000000 --- a/themes/webfiori/WebFioriTheme.php +++ /dev/null @@ -1,286 +0,0 @@ -setAuthor('Ibrahim Ali'); - $this->setName('WebFiori Theme'); - $this->setUrl('https://ibrahim-2017.blogspot.com/'); - $this->setLicenseName('MIT License'); - $this->setLicenseUrl('https://opensource.org/licenses/MIT'); - $this->setVersion('1.0.1'); - $this->setDescription('The main theme for WebFiori Framework.'); - $this->setImagesDirName('images'); - $this->setJsDirName('js'); - $this->setCssDirName('css'); - $this->addComponents([ - 'LangExt.php' - ]); - $this->setBeforeLoaded(function() - { - LangExt::extLang(); - }); - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - $page->getChildByID('main-content-area')->setClassName('wf-'.Page::dir().'-col-10'); - $page->getChildByID('side-content-area')->setClassName('wf-'.Page::dir().'-col-2'); - $page->getChildByID('page-body')->setClassName('wf-row'); - $page->getChildByID('page-header')->setClassName('wf-row-np'); - $page->getChildByID('page-footer')->setClassName('wf-row'); - }); - } - /** - * - * @param array $options An associative array of options. Available - * options are: - * - * @return HTMLNode - */ - public function createHTMLNode($options = []) { - $nodeType = isset($options['type']) ? $options['type'] : 'div'; - $withPadding = isset($options['with-padding']) ? $options['with-padding'] === true : true; - $withMargin = isset($options['with-margin']) ? $options['with-margin'] === true : true; - - if ($nodeType == 'div') { - $node = new HTMLNode(); - - return $node; - } else { - if ($nodeType == 'section') { - $node = new HTMLNode('section'); - - if (isset($options['h-level']) && $options['h-level'] > 0 && $options['h-level'] < 7) { - $h = new HTMLNode('h'.$options['h-level']); - } else { - $h = new HTMLNode('h1'); - } - $h->addTextNode($options['title']); - $node->addChild($h); - } else { - if ($nodeType == 'wf-row') { - $wp = $withPadding === true ? '' : '-np'; - $wm = $withMargin === true ? '' : '-nm'; - $node = new HTMLNode(); - $node->setClassName('wf-row'.$wm.$wp); - - return $node; - } else { - if ($nodeType == 'wf-col') { - $colSize = isset($options['size']) ? $options['size'] : 12; - - if ($colSize > 12 || $colSize < 1) { - $colSize = 12; - } - $wp = $withPadding === true ? '' : '-np'; - $wm = $withMargin === true ? '' : '-nm'; - $node = new HTMLNode(); - $node->setClassName('wf-'.Page::get()->getWritingDir().'-col-'.$colSize.$wm.$wp); - - return $node; - } else { - if ($nodeType == 'page-title') { - $titleRow = $this->createHTMLNode([ - 'type' => 'wf-row' - ]); - $titleRow->setID('page-title'); - $title = isset($options['title']) ? $options['title'] : Page::title(); - $h1 = new HTMLNode('h2'); - $h1->addTextNode($title); - $h1->setClassName('wf-'.Page::dir().'-col-10-nm-np'); - $titleRow->addChild($h1); - - return $titleRow; - } else { - if ($nodeType == 'status-label') { - $statusContainer = $this->createHTMLNode(['type' => 'wf-row']); - $statusContainer->setClassName($statusContainer->getAttributeValue('class').' status-label-container'); - $statusLabel = new PNode(); - $statusLabel->setID('status-label'); - $statusContainer->addChild($statusLabel); - - return $statusContainer; - } else { - if ($nodeType == 'input-element') { - $row = $this->createHTMLNode(['type' => 'wf-row']); - $label = isset($options['label']) ? $options['label'] : 'Input_label'; - $labelNode = new Label($label); - $inputId = isset($options['input-id']) ? $options['input-id'] : 'input-el'; - $labelNode->setAttribute('for', $inputId); - $inputType = isset($options['input-type']) ? $options['input-type'] : 'text'; - - if ($inputType == 'select') { - $row->addChild($labelNode); - $inputEl = new HTMLNode('select'); - $inputEl->setID($inputId); - - if (isset($options['select-data'])) { - foreach ($options['select-data'] as $data) { - $label = isset($data['label']) ? $data['label'] : 'Lbl'; - $val = isset($data['value']) ? $data['value']:null; - $isDisabled = isset($data['disabled']) ? $data['disabled'] === true : false; - - if ($val !== null) { - $o = new HTMLNode('option'); - $o->addTextNode($label); - $o->setAttribute('value', $val); - - if (isset($data['selected']) && $data['selected'] === true) { - $o->setAttribute('selected', ''); - } - - if ($isDisabled) { - $o->setAttribute('disabled', ''); - } - $inputEl->addChild($o); - } - } - } - $onInput = isset($options['on-input']) ? $options['on-input'] : "console.log(this.id+' has changed value.');"; - $inputEl->setAttribute('onchange', $onInput); - } else { - $inputEl = new Input($inputType); - $inputEl->setID($inputId); - $onInput = isset($options['on-input']) ? $options['on-input'] : "console.log(this.id+' has changed value.');"; - - if ($inputType == 'submit') { - $inputEl->setAttribute('onclick', $onInput); - $inputEl->setAttribute('value', $label); - } else { - if ($inputType == 'checkbox' || $inputType == 'radio') { - $labelNode->setStyle([ - 'display' => 'inline-block' - ]); - $row->addChild($inputEl); - $row->addChild($labelNode); - - if ($inputType == 'radio') { - $name = isset($options['name']) ? $options['name'] : 'radio-group'; - $inputEl->setName($name); - } - - return $row; - } else { - $row->addChild($labelNode); - $placeholder = isset($options['placeholder']) ? $options['placeholder'] : ''; - $inputEl->setAttribute('placeholder', $placeholder); - $inputEl->setAttribute('oninput', $onInput); - } - } - } - $row->addChild($inputEl); - - return $row; - } - } - } - } - } - } - } - } - public function getAsideNode() { - $menu = new HTMLNode('div'); - - return $menu; - } - - public function getFooterNode() { - $node = HTMLNode::loadComponent($this->getDirecotry().'footer.html', [ - 'version' => WF_VERSION, - 'version_type' => WF_VERSION_TYPE, - 'writing_dir' => Page::dir(), - 'contact_phone' => '013 xxx xxxx', - 'copyright' => 'All Rights Reserved', - 'contact_mail' => 'hello@example.com', - 'theme-dir' => $this->getDirectoryName(), - 'images-dir' => $this->getImagesDirName() - ]); - - return $node; - } - - public function getHeadNode() { - $headTag = new HeadNode(); - $headTag->addLink('icon', 'favicon.png'); - $headTag->addMeta('robots', 'index, follow'); - - return $headTag; - } - - public function getHeaderNode() { - $headerSec = HTMLNode::loadComponent($this->getDirecotry().'header.html', [ - 'menu-labels' => Page::translation()->get('menus/main-menu'), - 'home_link' => WebFioriApp::getAppConfig()->getBaseURL(), - 'dir' => Page::dir(), - 'site_name' => WebFioriApp::getAppConfig()->getWebsiteNames()[Page::lang()], - 'menu-links' => [ - 'm_1_link' => '#', - 'm_2_link' => '#', - 'm_3_link' => '#' - ], - ]); - - return $headerSec; - } -} - -return __NAMESPACE__; diff --git a/themes/webfiori/footer.html b/themes/webfiori/footer.html deleted file mode 100644 index 9e9bbba..0000000 --- a/themes/webfiori/footer.html +++ /dev/null @@ -1,27 +0,0 @@ - \ No newline at end of file diff --git a/themes/webfiori/header.html b/themes/webfiori/header.html deleted file mode 100644 index 97932a4..0000000 --- a/themes/webfiori/header.html +++ /dev/null @@ -1,23 +0,0 @@ -
- - - -
-

- {{site_name}} -

- -
-
\ No newline at end of file diff --git a/themes/webfiori108/WebFioriV108.php b/themes/webfiori108/WebFioriV108.php deleted file mode 100644 index ad759b2..0000000 --- a/themes/webfiori108/WebFioriV108.php +++ /dev/null @@ -1,346 +0,0 @@ -setVersion('1.0'); - $this->setAuthor('Ibrahim Ali'); - $this->setName('WebFiori V108'); - $this->setLicenseName('MIT License'); - $this->setUrl('https://ibrahim-2017.blogspot.com/'); - $this->setLicenseUrl('https://opensource.org/licenses/MIT'); - $this->setBeforeLoaded(function () - { - $activeSession = SessionsManager::getActiveSession(); - - if ($activeSession !== null) { - Page::lang($activeSession->getLangCode(true)); - } else { - Page::lang(WebFioriApp::getAppConfig()->getPrimaryLanguage()); - } - }); - $this->setAfterLoaded(function(Theme $theme) - { - $page = $theme->getPage(); - - $page->getChildByID('page-body')->setClassName('row ml-0 mr-0'); - $page->getChildByID('page-body')->setStyle([ - 'margin-top' => '50px' - ]); - $page->getDocument()->getBody()->setStyle([ - 'max-height' => '10px', - 'height' => '10px' - ]); - $page->getChildByID('main-content-area')->setClassName('col-10 p-5'); - $img = new HTMLNode('img'); - $img->setAttribute('src','assets/images/favicon.png'); - $img->setStyle([ - 'background-position' => 'left', - 'opacity' => '0.3', - 'position' => 'fixed', - 'top' => 0, - 'left' => '50px', - 'z-index' => -1, - ]); - $page->getDocument()->getBody()->addChild($img); - $page->addBeforeRender(function ($page) - { - $js = new \webfiori\ui\JsCode(); - $js->addCode("window.Prism = window.Prism || {};"); - $page->getDocument()->getHeadNode()->addChild($js); - }); - }); - } - - public function createHTMLNode($options = []) { - $nodeType = isset($options['type']) ? $options['type'] : ''; - $elementId = isset($options['element-id']) ? $options['element-id'] : null; - - if ($nodeType == 'section') { - $sec = new HTMLNode('section'); - $hLvl = isset($options['h-level']) ? $options['h-level'] : 3; - $hLevelX = $hLvl > 0 && $hLvl < 7 ? $hLvl : 1; - $h = new HTMLNode('h'.$hLevelX); - $title = isset($options['title']) ? $options['title'] : 'Sec_Title'; - $h->addTextNode($title); - $sec->addChild($h); - - if ($elementId !== null) { - $h->setID($elementId); - } - - return $sec; - } else { - if ($nodeType == 'col') { - $node = new HTMLNode(); - $colSize = isset($options['size']) ? $options['size'] : null; - - if ($colSize >= 1 && $colSize <= 12) { - $node->setClassName('col-'.$colSize); - } else { - $node->setClassName('col'); - } - - return $node; - } else { - if ($nodeType == 'vertical-nav-bar') { - $mainNav = new HTMLNode('nav'); - $mainNav->setClassName('navbar navbar-expand-lg navbar-light p-0'); - $navbarId = isset($options['id']) ? $options['id'] : 'nav'.substr(hash('sha256',date('Y-m-d H:i:s')), 0,10); - $button = new HTMLNode('button'); - $button->setClassName('navbar-toggler'); - $button->addTextNode('', false); - $button->setAttribute('data-toggle', 'collapse'); - $button->setAttribute('data-target', '#'.$navbarId); - $button->setAttribute('type', 'button'); - $button->setAttribute('aria-controls', ''.$navbarId); - $button->setAttribute('aria-expanded', 'false'); - $mainNav->addChild($button); - - $navItemsContainer = new HTMLNode(); - $navItemsContainer->setID($navbarId); - $navItemsContainer->setClassName('collapse navbar-collapse'); - $mainNav->addChild($navItemsContainer); - - $mainLinksUl = new UnorderedList(); - $mainLinksUl->setClassName('navbar-nav flex-column'); - $listItems = isset($options['nav-links']) ? $options['nav-links'] : []; - $index = 0; - - foreach ($listItems as $listItemArr) { - $linkLabel = isset($listItemArr['label']) ? $listItemArr['label'] : 'Item_Lbl'; - $itemLink = isset($listItemArr['link']) ? $listItemArr['link'] : '#'; - $isActive = isset($listItemArr['is-active']) && $listItemArr['is-active'] === true ? true : false; - $mainLinksUl->addListItem(''.$linkLabel.'', false); - - if ($isActive === true) { - $mainLinksUl->getChild($index)->setClassName('nav-item active'); - } else { - $mainLinksUl->getChild($index)->setClassName('nav-item'); - } - $index++; - } - $subLists = isset($options['sub-lists']) ? $options['sub-lists'] : []; - - foreach ($subLists as $subList) { - $listTxt = isset($subList['label']) ? $subList['label'] : 'Sub_list'; - $link = isset($subList['link']) ? $subList['link'] : null; - $isActive = isset($subList['is-active']) && $subList['is-active'] === true ? true : false; - $subListItems = isset($subList['list-items']) ? $subList['list-items']:[]; - $li = new ListItem(); - $li->setClassName('nav-item'); - $liDiv = new HTMLNode(); - $li->addChild($liDiv); - $liDiv->setClassName('btn-group dropright'); - $textButton = new HTMLNode('button'); - $textButton->setClassName('btn btn-secondary p-0'); - $textButton->setAttribute('type', 'button'); - $textButton->setStyle([ - 'background' => 'transparent', - 'border' => '0px' - ]); - $liDiv->addChild($textButton); - - if ($link !== null) { - $textButton->addTextNode(''.$listTxt.'', false); - } else { - $textButton->addTextNode($listTxt); - } - $expandButton = new HTMLNode('button'); - $expandButton->setClassName('btn btn-secondary dropdown-toggle dropdown-toggle-split'); - $expandButton->setStyle([ - 'background' => 'transparent', - 'border' => '0px' - ]); - $expandButton->setAttributes([ - 'type' => 'button', - 'data-toggle' => "dropdown", - 'aria-haspopup' => "true", - 'aria-expanded' => "false" - ]); - $liDiv->addChild($expandButton); - $subItemsContainer = new HTMLNode(); - $liDiv->addChild($subItemsContainer); - $subItemsContainer->setAttributes([ - 'class' => 'dropdown-menu', - 'x-placement' => 'right-start', - 'style' => 'position: absolute; transform: translate3d(159px, 0px, 0px); top: 0px; left: 0px; will-change: transform;', - ]); - $index = 0; - - foreach ($subListItems as $listItem) { - $linkLabel = isset($listItem['label']) ? $listItem['label'] : 'Item_Lbl'; - $itemLink = isset($listItem['link']) ? $listItem['link'] : '#'; - $isActive = isset($listItem['is-active']) && $listItem['is-active'] === true ? true : false; - $linkNode = new Anchor($itemLink, $linkLabel); - $linkNode->setClassName('dropdown-item'); - $subItemsContainer->addChild($linkNode); - - if ($isActive === true) { - $subItemsContainer->getChild($index)->setClassName('active'); - } - $index++; - } - $mainLinksUl->addChild($li); - } - $navItemsContainer->addChild($mainLinksUl); - - return $mainNav; - } else { - if ($nodeType == 'container') { - $node = new HTMLNode(); - $node->setClassName('container'); - - return $node; - } else { - if ($nodeType == 'row') { - $node = new HTMLNode(); - $node->setClassName('row'); - - return $node; - } else { - if ($nodeType == 'page-title') { - $titleRow = $this->createHTMLNode(['type' => 'row']); - $h1 = new HTMLNode('h2'); - $title = isset($options['title']) ? $options['title'] : Page::title(); - $h1->addTextNode($title,false); - $h1->setClassName('page-title pb-2 mt-4 mb-2 border-bottom'); - $titleRow->addChild($h1); - - return $titleRow; - } else { - if ($nodeType == 'row') { - $node = new HTMLNode(); - $node->setClassName('row'); - - return $node; - } - } - } - } - } - } - } - $node = new HTMLNode(); - - return $node; - } - - public function getAsideNode() { - $aside = new HTMLNode(); - $aside->setClassName('col-2'); - - return $aside; - } - - public function getFooterNode() { - $footer = new HTMLNode('footer'); - $footer->setClassName('bd-footer text-muted'); - $footer->setClassName('container-fluid p-md-4'); - $footerLinksUl = new UnorderedList(); - $footerLinksUl->setClassName('nav justify-content-center'); - $footerLinksUl->addListItems([ - 'GitHub', - 'Twitter', - 'Telegram' - ], false); - $footerLinksUl->getChild(0)->setClassName('nav-item'); - $footerLinksUl->getChild(1)->setClassName('nav-item ml-3'); - $footerLinksUl->getChild(2)->setClassName('nav-item ml-3'); - $footer->addChild($footerLinksUl); - $powerdByNode = new HTMLNode('p'); - $powerdByNode->addTextNode('Powered by: WebFiori Framework v'.WF_VERSION.'. ' - .'Code licensed under the MIT License.', false); - $footer->addChild($powerdByNode); - $img = new HTMLNode('img'); - $img->setAttribute('src', 'assets/images/favicon.png'); - $img->setAttribute('alt', 'logo'); - $img->setStyle([ - 'height' => '25px' - ]); - $footer->addChild($img); - $copywriteNotice = new HTMLNode('p'); - $copywriteNotice->addTextNode('All Rights Reserved © '.date('Y')); - $footer->addChild($copywriteNotice); - - return $footer; - } - public function getHeadNode() { - $head = new HeadNode(); - $head->addCSS('https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css'); - $head->addJs('https://code.jquery.com/jquery-3.4.1.slim.min.js'); - $head->addJs('https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js'); - $head->addJs('https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js'); - - return $head; - } - - public function getHeaderNode() { - $header = new HTMLNode('header'); - $header->setClassName('container-fluid'); - $mainNav = new HTMLNode('nav'); - $header->addChild($mainNav); - $mainNav->setClassName('navbar navbar-expand-lg navbar-light fixed-top'); - $mainNav->setStyle([ - 'background-color' => '#c1ec9b', - 'padding' => '0' - ]); - $logo = new HTMLNode('img', [ - 'id' => 'main-logo', - 'src' => 'favicon.png', - 'alt' => 'logo', - 'style' => 'width:40px' - ]); - $logoLink = new Anchor(WebFioriApp::getAppConfig()->getHomePage(), $logo->toHTML()); - $logoLink->setClassName('navbar-brand ml-3'); - $mainNav->addChild($logoLink); - - $button = new HTMLNode('button'); - $button->setClassName('navbar-toggler'); - $button->addTextNode('', false); - $button->setAttribute('data-toggle', 'collapse'); - $button->setAttribute('data-target', '#navItemsContainer'); - $button->setAttribute('type', 'button'); - $button->setAttribute('aria-controls', 'navItemsContainer'); - $button->setAttribute('aria-expanded', 'false'); - $mainNav->addChild($button); - - $navItemsContainer = new HTMLNode(); - $navItemsContainer->setID('navItemsContainer'); - $navItemsContainer->setClassName('collapse navbar-collapse'); - $mainNav->addChild($navItemsContainer); - - $mainLinksUl = new UnorderedList(); - $mainLinksUl->setClassName('navbar-nav justify-content-center'); - $mainLinksUl->addListItems([ - 'Download', - 'API Docs', - 'Learn', - 'Contribute' - ], false); - $mainLinksUl->getChild(0)->setClassName('nav-item'); - $mainLinksUl->getChild(1)->setClassName('nav-item'); - $mainLinksUl->getChild(2)->setClassName('nav-item'); - $mainLinksUl->getChild(3)->setClassName('nav-item'); - $navItemsContainer->addChild($mainLinksUl); - - return $header; - } -} - -return __NAMESPACE__;