{"id":15068546,"url":"https://github.com/eftec/routeone","last_synced_at":"2025-03-17T14:12:27.452Z","repository":{"id":56975555,"uuid":"192809317","full_name":"EFTEC/RouteOne","owner":"EFTEC","description":"It is a library","archived":false,"fork":false,"pushed_at":"2024-12-31T11:24:33.000Z","size":516,"stargazers_count":29,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-04T22:58:40.384Z","etag":null,"topics":["php-library","php7","route"],"latest_commit_sha":null,"homepage":"https://www.eftec.cl","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EFTEC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-19T21:53:38.000Z","updated_at":"2024-12-31T11:24:20.000Z","dependencies_parsed_at":"2024-10-13T04:51:14.899Z","dependency_job_id":null,"html_url":"https://github.com/EFTEC/RouteOne","commit_stats":{"total_commits":65,"total_committers":3,"mean_commits":"21.666666666666668","dds":0.3076923076923077,"last_synced_commit":"10b5734c1b4859c3f5f246e3dc9a121df1990926"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EFTEC%2FRouteOne","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EFTEC%2FRouteOne/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EFTEC%2FRouteOne/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EFTEC%2FRouteOne/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EFTEC","download_url":"https://codeload.github.com/EFTEC/RouteOne/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244047646,"owners_count":20389206,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php-library","php7","route"],"created_at":"2024-09-25T01:38:02.661Z","updated_at":"2025-03-17T14:12:27.396Z","avatar_url":"https://github.com/EFTEC.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RouteOne\r\nIt reads the URL route and parses the values of path, so it could be interpreted manually or automatically in the fastest way possible (for example, to implement an MVC system).\r\n\r\n[![Packagist](https://img.shields.io/packagist/v/eftec/routeone.svg)](https://packagist.org/packages/eftec/routeone)\r\n[![Total Downloads](https://poser.pugx.org/eftec/routeone/downloads)](https://packagist.org/packages/eftec/routeone)\r\n[![Maintenance](https://img.shields.io/maintenance/yes/2025.svg)]()\r\n[![composer](https://img.shields.io/badge/composer-%3E1.6-blue.svg)]()\r\n[![php](https://img.shields.io/badge/php-%3E7.4-green.svg)]()\r\n[![php](https://img.shields.io/badge/php-%3E8.4-green.svg)]()\r\n[![coverage](https://img.shields.io/badge/coverage-80%25-green)]()\r\n[![compatible](https://img.shields.io/badge/compatible-linux%7Cwindows%7Cmacos-green)]()\r\n\r\nUnlikely other libraries, this library does not have dependencies, and it is contained in a single class, so it is compatible with any PHP project, for example WordPress, Laravel, Drupal, a custom PHP project, etc.\r\n\r\nThis library is based in **CoC Convention over Configuration**. It reduces the boilerplate but it has fixed  functionalities.  This library does not allow to use custom \"routes\" but it covers practically all cases, so it increases the performance and usability while it sacrifices flexibility.\r\n\r\n## Table of contents\r\n\r\n\u003c!-- TOC --\u003e\r\n* [RouteOne](#routeone)\r\n  * [Table of contents](#table-of-contents)\r\n  * [Example:](#example)\r\n  * [What it does?](#what-it-does)\r\n    * [What is **$id**, **$idparent** and **$event**?](#what-is-id-idparent-and-event)\r\n    * [**id**](#id)\r\n    * [**idparent**](#idparent)\r\n    * [**event**](#event)\r\n    * [**Module**](#module)\r\n  * [Getting started](#getting-started)\r\n    * [Using the cli (recommended)](#using-the-cli-recommended)\r\n      * [manual installation](#manual-installation)\r\n      * [1) Create a .htaccess file in the folder root (Apache)](#1-create-a-htaccess-file-in-the-folder-root-apache)\r\n      * [Or configure nginx.conf (Nginx) Linux (not tested)](#or-configure-nginxconf-nginx-linux-not-tested)\r\n      * [Or configure nginx.conf (Nginx) Windows](#or-configure-nginxconf-nginx-windows)\r\n  * [Using Paths](#using-paths)\r\n    * [clearPath()](#clearpath)\r\n    * [addPath()](#addpath)\r\n    * [fetchPath()](#fetchpath)\r\n  * [Methods](#methods)\r\n    * [__construct($base='', $forcedType=null, $isModule=false)](#__constructbase-forcedtypenull-ismodulefalse)\r\n    * [getQuery($key,$valueIfNotFound=null)](#getquerykeyvalueifnotfoundnull)\r\n    * [setQuery($key,$value)](#setquerykeyvalue)\r\n    * [fetch](#fetch)\r\n    * [callObjectEx](#callobjectex)\r\n    * [callFile($fileStructure='%s.php',$throwOnError=true)](#callfilefilestructuresphpthrowonerrortrue)\r\n    * [getHeader()](#getheader)\r\n    * [getBody()](#getbody)\r\n    * [](#)\r\n    * [getCurrentUrl($withoutFilename = true)](#getcurrenturlwithoutfilename--true)\r\n    * [getCurrentServer()](#getcurrentserver)\r\n    * [setCurrentServer($serverName)](#setcurrentserverservername)\r\n    * [getUrl($extraQuery = '',$includeQuery=false)](#geturlextraquery--includequeryfalse)\r\n    * [url($module,$controller,$action,$id,$idparent)](#urlmodulecontrolleractionididparent)\r\n    * [urlFront($module,$category,$subcategory,$subsubcategory,$id)](#urlfrontmodulecategorysubcategorysubsubcategoryid)\r\n    * [alwaysWWW($https = false)](#alwayswwwhttps--false)\r\n    * [alwaysHTTPS()](#alwayshttps)\r\n    * [alwaysNakedDomain($https = false)](#alwaysnakeddomainhttps--false)\r\n  * [fields](#fields)\r\n  * [Whitelist](#whitelist)\r\n    * [Whitelist input.](#whitelist-input)\r\n  * [CLI](#cli)\r\n  * [Changelog](#changelog)\r\n\u003c!-- TOC --\u003e\r\n\r\n## Example:\r\n\r\nLet's say we have the next URL http://somedomain.dom/Customer/Update/2 This library converts this URL into variables that\r\ncould be process or directly calling a method.\r\n\r\nroute.php\r\n```php\r\n$route=new RouteOne('http://www.somedomain.dom');\r\n$route-\u003eaddPath('api/{controller}/{action}/{id}'); \r\n$route-\u003eaddPath('{controller}/{action}/{id}/{idparent}');\r\n$route-\u003efetchPath();\r\n$this-\u003ecallObjectEx('cocacola\\controller\\{controller}Controller');\r\n```\r\n\r\ncontroller\\CustomerController.php class\r\n```php\r\nnamespace cocacola\\controller\\;\r\nclass CustomerController {\r\n   public function updateAction($id=null,$idparent=null,$event=null) {\r\n      echo \"We want to update the customer $id\";\r\n   }\r\n}\r\n \r\n```\r\n\r\n\r\n## What it does?\r\n\r\nLet's say we do the next operation:\r\n\r\nA user calls the next website http://somedomain.com/Customer/Insert, he wants to show a form to insert a customer\r\n\r\n```php\r\nuse \\eftec\\routeone\\RouteOne;\r\n$route=new RouteOne('.',null,null); // Create the RouteOneClass\r\n$route-\u003efetch(); // fetch all the input values (from the route, get, post and such).\r\n$route-\u003ecallObject('somenamespace\\\\controller\\\\%sController'); // where it will call the  class CustomerController* \r\n```\r\n\r\nor\r\n\r\n```php\r\nuse eftec\\routeone\\RouteOne;\r\n$route=new RouteOne('.',null,null); // Create the RouteOneClass\r\n$route-\u003efetch(); // fetch all the input values (from the route, get, post and such).\r\n$route-\u003ecallObjectEx('somenamespace\\\\controller\\\\{controller}Controller'); // where it will call the  class CustomerController* \r\n```\r\n\r\n\r\nThis code calls to the method **InsertActionGet** (GET), **InsertActionPost** (POST) or **InsertAction** (GET/POST)\r\ninside the class **Customer**\r\n\r\nThe method called is written as follows:\r\n\r\n```php\r\nclass Customer {\r\n    public function insertAction($id=\"\",$idparent=\"\",$event=\"\") {\r\n        // here we do our operation.\r\n    }\r\n}\r\n```\r\n\r\n### What is **$id**, **$idparent** and **$event**?\r\n\r\n### **id**\r\n\r\nLet's se we want to **Update** a **Customer** number **20**, then we could call the next page\r\n\r\n\u003e http://somedomain.com/Customer/Update/20\r\n\r\nwhere 20 is the \"$id\" of the customer to edit (it could be a number of a string)\r\n\r\n### **idparent**\r\n\r\nAnd what if we want to **Update** a **Customer** number **20** of the business **APPL**\r\n\r\n\u003e http://somedomain.com/Customer/Update/20/APPL\r\n\r\nWhere APPL is the **idparent**\r\n\r\n### **event**\r\n\r\nNow, let's say we click on some button, or we do some action.  It could be captured by the field **_event**, and it\r\nis read by the argument **$event**. This variable could be sent via GET or POST.\r\n\r\n\u003e http://somedomain.com/Customer/Update/20/APPL?_event=click\r\n\r\n### **Module**\r\n\r\n\u003e Note: Modules are obtained automatically if you use addPath() and fetchPath(), so you don't need to specify it.\r\nNow, let's say our system is modular, and we have several customers (internal customers, external, etc.)\r\n\r\n```php\r\n$route=new RouteOne('.',null,true); // true indicates it is modular.\r\n```\r\n\r\nor\r\n\r\n```php\r\n$route=new RouteOne('.',null,['Internal']); // or we determine the module automatically. In this case, every url that starts with Internal\r\n```\r\n\r\nthen\r\n\r\n```php\r\n$route-\u003efetch(); \r\n$route-\u003ecallObject('somenamespace\\\\%2s%\\\\controller\\\\%1sController');\r\n```\r\n\r\n\u003e http://somedomain.com/Internal/Customer/Update/20/APPL?_event=click\r\n\r\nThen, the first ramification is the name of the module (**Internal**) and it calls the class **somenamespace\\Internal\\controller\\CustomerController**\r\n\r\n\r\n## Getting started\r\n\r\n### Using the cli (recommended)\r\n\r\n* Install the library\r\n\r\n\u003e composer require eftec/routeone\r\n\r\n* Execute the binary in the root folder\r\n\r\nLinux:\r\n\r\n```shell\r\nvendor/bin/routeonecli -init  (if the binary does not work, then chage the permission to execution)\r\n```\r\nWindows:\r\n```shell\r\n.\\vendor\\bin\\routeonecli.bat -init\r\n```\r\n\r\nIt will create the file .htaccess and the file route.php and route.php will have a default configuration.\r\n\r\n* Edit the file route.php and change the next lines:\r\n\r\n```php\r\nconst BASEURL=\"http://localhost\"; // Base url edit this value.\r\nconst BASEWEBNS=\"eftec\\\\controller\"; // Base namespace (web) edit this value\r\nconst BASEAPINS=\"eftec\\\\api\"; // Base namespace (api) edit this value\r\n```\r\nLater, you can add or edit the code in this file.\r\n\r\n#### manual installation\r\n\r\n#### 1) Create a .htaccess file in the folder root (Apache)\r\n\r\n```\r\n\u003cIfModule mod_rewrite.c\u003e\r\n    \u003cIfModule mod_negotiation.c\u003e\r\n        Options -MultiViews -Indexes\r\n    \u003c/IfModule\u003e\r\n\r\n    RewriteEngine On\r\n    DirectoryIndex route.php\r\n\r\n    # Handle Authorization Header\r\n    RewriteCond %{HTTP:Authorization} .\r\n    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\r\n\r\n    # Redirect Trailing Slashes If Not A Folder...\r\n    RewriteCond %{REQUEST_FILENAME} !-d\r\n    RewriteCond %{REQUEST_URI} (.+)/$\r\n    RewriteRule ^ %1 [L,R=301]\r\n\r\n    # Send Requests To Front Controller...\r\n    RewriteCond %{REQUEST_FILENAME} !-d\r\n    RewriteCond %{REQUEST_FILENAME} !-f\r\n    RewriteRule ^ route.php?req=$1 [L,QSA]\r\n\u003c/IfModule\u003e\r\n```\r\n\r\n\u003e If your web host doesn't allow the FollowSymlinks option, try replacing it with Options +SymLinksIfOwnerMatch.\r\n\r\n\r\n\u003e The important line is:    \r\n\u003e RewriteRule ^(.*)$ route.php?req=$1 [L,QSA]   # The router to call.\r\n\r\n#### Or configure nginx.conf (Nginx) Linux (not tested)\r\n\r\n```\r\nserver {\r\n    listen 80;\r\n    server_name localhost;\r\n    root /example.com/public;\r\n\r\n    add_header X-Frame-Options \"SAMEORIGIN\";\r\n    add_header X-XSS-Protection \"1; mode=block\";\r\n    add_header X-Content-Type-Options \"nosniff\";\r\n\r\n    index index.html index.htm index.php;\r\n\r\n    charset utf-8;\r\n\r\n    location / {\r\n        try_files $uri $uri/ /router.php?req=$document_uri\u0026$query_string;\r\n    }\r\n\r\n    location = /favicon.ico { access_log off; log_not_found off; }\r\n    location = /robots.txt  { access_log off; log_not_found off; }\r\n\r\n    error_page 404 /index.php;\r\n\r\n    location ~ \\.php$ {\r\n        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;\r\n        fastcgi_index index.php;\r\n        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;\r\n        include fastcgi_params;\r\n    }\r\n\r\n    location ~ /\\.(?!well-known).* {\r\n        deny all;\r\n    }\r\n}\r\n\r\n```\r\n\r\n\u003e The important line is:  \r\n\u003e try_files $uri $uri/ /router.php?req=$document_uri\u0026$query_string;\r\n\r\n#### Or configure nginx.conf (Nginx) Windows\r\n\r\n```\r\nserver {\r\n    listen 80;\r\n    server_name localhost;\r\n    root c:/www;\r\n\r\n    add_header X-Frame-Options \"SAMEORIGIN\";\r\n    add_header X-XSS-Protection \"1; mode=block\";\r\n    add_header X-Content-Type-Options \"nosniff\";\r\n\r\n    index index.html index.htm index.php;\r\n\r\n    charset utf-8;\r\n\r\n    location / {\r\n        try_files $uri $uri/ /router.php?req=$document_uri\u0026$query_string;\r\n    }\r\n\r\n    location = /favicon.ico { access_log off; log_not_found off; }\r\n    location = /robots.txt  { access_log off; log_not_found off; }\r\n\r\n    error_page 404 /index.php;\r\n\r\n    location ~ \\.php$ {\r\n        fastcgi_pass   127.0.0.1:9000;\r\n        fastcgi_index  index.php;\r\n        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;\r\n        include fastcgi_params;\r\n    }\r\n\r\n    location ~ /\\.(?!well-known).* {\r\n        deny all;\r\n    }\r\n}\r\n\r\n```\r\n\u003e The important line is:  \r\n\u003e try_files $uri $uri/ /router.php?req=$document_uri\u0026$query_string;\r\n\r\n\r\nwhere **router.php** is the file that it will work as router.  ?req=$1 is important because the system will read the route from \"req\"\r\n\r\n```php \r\n// router.php\r\n$route=new RouteOne(); // Create the RouteOneClass\r\n$route-\u003efetch(); // fetch all the input values (from the route, get, post and such).\r\n$route-\u003ecallObject('somenamespace\\\\controller\\\\%sController'); // where it will call the  class \\somenamespace\\controller\\CustomerController  \r\n```\r\n\r\n\u003e Note:\r\n\u003e\r\n\u003e If you want to use an argument different as \"req\", then you can change it using the next code:\r\n\u003e\r\n\u003e $route-\u003eargumentName='newargument';\r\n\r\n\r\n\r\n## Using Paths\r\n\r\nSince 1.21, it is possible to use a custom path instead of a pre-defined path. It is the recommended way.\r\nThe other method is still present.\r\n\r\n### clearPath()\r\n\r\nSyntax:\r\n\r\n\u003eclearPath()\r\n\r\nIt clears all the paths defined\r\n\r\n### addPath()\r\nSyntax:\r\n\u003e addPath($path, $name = null,callable $middleWare=null)\r\n\r\nIt adds a paths that could be evaluated using fetchPath()    \r\n**Example:**\r\n```php\r\n$this-\u003eaddPath('api/{controller}/{action}/{id:0}','apipath');  \r\n$this-\u003eaddPath('/api/{controller}/{action}/{id:0}/','apipath'); // \"/\" at the beginner and end are trimmed.  \r\n$this-\u003eaddPath('{controller}/{action}/{id:0}','webpath');  \r\n$this-\u003eaddPath('{controller:root}/{action}/{id:0}','webpath'); // root path using default  \r\n$this-\u003eaddPath('somepath','namepath',  \r\n     function(callable $next,$id=null,$idparent=null,$event=null) {  \r\n         echo \"middleware\\n\";  \r\n         $result=$next($id,$idparent,$event); // calling the controller  \r\n         echo \"endmiddleware\\n\";  \r\n          return $result;  \r\n      });  \r\n```\r\n**Note:**    \r\nThe first part of the path, before the \"{\" is used to determine which path will be used.    \r\nExample \"path/{controller}\" and \"path/{controller}/{id}\", the system will consider that are the same path  \r\n\r\n* **parameter** string        $path       The path, example \"aaa/{controller}/{action:default}/{id}\"    \r\n  Where **default** is the optional default value.   \r\n  * **{controller}**: The controller (class) to call  \r\n  * **{action}**: The action (method) to call  \r\n  * **{verb}**: The verb of the action (GET/POST,etc.)  \r\n  * **{type}**: The type (value)  \r\n  * **{module}**: The module (value)  \r\n  * **{id}**: The id (value)  \r\n  * **{idparent}**: The id parent (value)  \r\n  * **{category}**: The category (value)  \r\n  * **{subcategory}**: The subcategory (value)  \r\n  * **{subsubcategory}**: The subsubcategory (value)  \r\n\r\n* **parameter** string|null   $name       (optional), the name of the path  \r\n* **parameter** callable|null $middleWare A callable function used for middleware.  \r\n  The first argument of the function must be a callable method  \r\n  The next arguments must be the arguments defined by callObjectEx  \r\n(id,idparent,event)\r\n\r\n* The path could start with a static location but the rest of the path must be defined by variables (enclosed by {})\r\nand separated by \"/\".  \r\n* You can also set a default value for a path by writing \":\" after the name of the variable: {name:defaultvalue}  \r\n* The **name** could be obtained using $this-\u003ecurrentPath. If you add a name with the same name, then it is replaced.  \r\n* If you don't set a name, then it uses an autonumeric.  \r\n* The **name** is also returned when you call $this-\u003efetchPath()  \r\n\r\n\r\nExample:\r\n\r\n```php\r\n$this-\u003eaddPath('{controller}/{id}/{idparent}');\r\n$this-\u003eaddPath('myapi/otherfolder/{controller}/{id}/{idparent}');\r\n$this-\u003eaddPath('{controller:defcontroller}/{action:defaction}/{id:1}/{idparent:2}');\r\n\r\n// url: /dummy/10/20 =\u003e(controller: dummy, id=10, idparent=20)\r\n// url: /myapi/otherfolder/dummy/10/20  =\u003e(controller: dummy, id=10, idparent=20)\r\n```\r\n\r\n\u003e You can define different paths, however it only uses the first part of the path that matches some URL.\r\n\u003e 'path/somepath/{id}' will work\r\n\u003e 'path/{id}/other' will not work\r\n\r\n### fetchPath()\r\n\r\nSyntax:\r\n\r\n\u003e fetchPath()\r\n\r\nIt fetches the path previously defined by addPath, and it returns the name(or number) of the path. If not found, then it returns false\r\n\r\nExample:\r\n\r\n```php\r\n$route=new RouteOne('http://www.example.dom');\r\n$route-\u003eaddPath('{controller}/{id}/{idparent}','optionalname');\r\n// if the url is : http://www.example.dom/customer/1/200 then it will return\r\necho $route-\u003efetchPath(); // optionalname\r\necho $route-\u003econtroller; // customer\r\necho $route-\u003eid; // 1\r\necho $route-\u003eidparent; // 200\r\n\r\n```\r\n\r\n\r\n## Methods\r\n\r\n### __construct($base='', $forcedType=null, $isModule=false)\r\n\r\n* string $base base url\r\n* string $forcedType=['api','ws','controller','front']\\[$i]\u003cbr\u003e\r\n  \u003cb\u003eapi\u003c/b\u003e then it expects a path as api/controller/action/id/idparent\u003cbr\u003e\r\n  \u003cb\u003ews\u003c/b\u003e then it expects a path as ws/controller/action/id/idparent\u003cbr\u003e\r\n  \u003cb\u003econtroller\u003c/b\u003e then it expects a path as controller/action/id/idparent\u003cbr\u003e\r\n  \u003cb\u003efront\u003c/b\u003e then it expects a path as /category/subcategory/subsubcategory/id\u003cbr\u003e\r\n* bool   $isModule if true then the route start reading a module name\u003cbr\u003e\r\n  \u003cb\u003efalse\u003c/b\u003e controller/action/id/idparent\u003cbr\u003e\r\n  \u003cb\u003etrue\u003c/b\u003e module/controller/action/id/idparent\u003cbr\u003e       \r\n  \u003cb\u003earray\u003c/b\u003e if the value is an array then the value is determined if the first part of the path is in the array.\u003cbr\u003e\r\n  Example ['modulefolder1','modulefolder2']\u003cbr\u003e\r\n\r\n### getQuery($key,$valueIfNotFound=null)\r\n\r\nIt gets a query value (URL).\r\n\r\n\u003eNote: This query does not include the values \"req\",\"_event\" and \"_extra\"\r\n\r\nExample:\r\n\r\n```php \r\n// http://localhost/..../?id=hi\r\n$id=$router-\u003egetQuery(\"id\"); // hi\r\n$nf=$router-\u003egetQuery(\"something\",\"not found\"); // not found\r\n```\r\n\r\n### setQuery($key,$value)\r\n\r\nIt sets a query value\r\n\r\nExample:\r\n\r\n```php \r\n$route-\u003esetQuery(\"id\",\"hi\");\r\n$id=$router-\u003egetQuery(\"id\"); // hi\r\n```\r\n\r\n\r\n### fetch\r\n\r\nSintax:\r\n\u003e fetchPath()\r\n\r\nFetch the values from the route, and the values are processed.\r\n\r\n### callObjectEx\r\n\r\nSintax\r\n\u003e callObjectEx($classStructure, $throwOnError, $method, $methodGet, $methodPost,$arguments,$injectArguments)\r\n\r\nIt creates a new instance of an object (for example, a Controller object) and calls the method.\u003cbr\u003e\r\nNote: It is an advanced version of this::callObject()\u003cbr\u003e\r\nThis method uses {} to replace values based in the next variables:\u003cbr\u003e\r\n\r\n| Tag              | Description                                        |\r\n|------------------|----------------------------------------------------|\r\n| {controller}     | The name of the controller                         |\r\n| {action}         | The current action                                 |\r\n| {event}          | The current event                                  |\r\n| {type}           | The current type of path (ws,controller,front,api) |\r\n| {module}         | The current module (if module is active)           |\r\n| {id}             | The current id                                     |\r\n| {idparent}       | The current idparent                               |\r\n| {category}       | The current category                               |\r\n| {subcategory}    | The current subcategory                            |\r\n| {subsubcategory} | The current subsubcategory                         |\r\n\r\n\u003cb\u003eExample:\u003c/b\u003e\r\n\r\n```php\r\n// controller example http://somedomain/Customer/Insert/23\r\n$this-\u003ecallObjectEx('cocacola\\controller\\{controller}Controller');\r\n// it calls the method cocacola\\controller\\Customer::InsertAction(23,'','');\r\n\r\n// front example: http://somedomain/product/coffee/nescafe/1\r\n$this-\u003ecallObjectEx('cocacola\\controller\\{category}Controller' // the class to call\r\n        ,false // if error then it throw an error\r\n        ,'{subcategory}' // the method to call (get, post or any other method)\r\n        ,null // the method to call (method get)\r\n        ,null // the method to call (method post)\r\n        ,['subsubcategory','id'] // the arguments to call the method\r\n        ,['arg1','arg2']); // arguments that will be passed to the constructor of the instance \r\n// it calls the method cocacola\\controller\\product::coffee('nescafe','1');\r\n```\r\n\r\nCall a method inside an object using the current route.\r\n\r\n**Example:**\r\n\r\nRouter:\r\n\r\n```php\r\n$databaseService=new SomeDatabaseService();\r\n$route=new RouteOne();\r\n\r\n$route-\u003ecallObjectEx('cocacola\\controller\\{controller}Controller' // the class to call\r\n        ,false // if error then it throw an error\r\n        ,'{action}Action' // the method to call (get, post or any other method)\r\n        ,'{action}Action{verb}' // the method to call (method get)\r\n        ,'{action}Action{verb}' // the method to call (method post)\r\n        ,['id', 'idparent', 'event'] // the arguments to call the method\r\n        ,[$databaseService,$route]); // (optional)arguments that will be passed to the constructor of the instance \r\n\r\n```\r\n\r\nController:\r\n\r\n```php\r\nnamespace cocacola\\controller;\r\nclass CustomerController {\r\n\tprotected $databaseService;\r\n    protected $route;\r\n    public function __construct($databaseService,$route) {\r\n        // optional: injecting services\r\n\t\t$this-\u003edatabaseService=$databaseService;\r\n\t\t$this-\u003eroute=$route;        \r\n    }\r\n    // any action GET or POST\r\n    public function GreenAction($id=\"\",$idparent=\"\",$event=\"\") {\r\n    }\r\n    // GET only action (optional)\r\n    public function BlueActionGET($id=\"\",$idparent=\"\",$event=\"\") {\r\n        // **my code goes here.**\r\n    }    \r\n    // POST only action (optional)\r\n    public function YellowActionPOST($id=\"\",$idparent=\"\",$event=\"\") {\r\n        // **my code goes here.**\r\n    }    \r\n    // GET only action (optional)\r\n    public function RedActionGET($id=\"\",$idparent=\"\",$event=\"\") {\r\n        // **my code goes here.**\r\n    }      \r\n    // any action GET or POST\r\n    public function RedAction($id=\"\",$idparent=\"\",$event=\"\") {\r\n        // **my code goes here.**\r\n    }      \r\n    \r\n}\r\n```\r\nResults:\r\n\r\n| url                                                      | method called                                     |\r\n|----------------------------------------------------------|---------------------------------------------------|\r\n| http://localhost/Customer/Green (GET)                    | GreenAction                                       |\r\n| http://localhost/Customer/Green/20/30?_event=click (GET) | GreenAction($id=20, $idparent=30, $event='click') |\r\n| http://localhost/Customer/Green (POST)                   | GreenAction                                       |\r\n| http://localhost/Customer/Blue (GET)                     | BlueActionGET                                     |\r\n| http://localhost/Customer/Blue (POST)                    | ERROR                                             |\r\n| http://localhost/Customer/Yellow (GET)                   | ERROR                                             |\r\n| http://localhost/Customer/Yellow (POST)                  | YellowActionPOST                                  |\r\n| http://localhost/Customer/Red (GET)                      | RedActionGET (It has priority over RedAction)     |\r\n| http://localhost/Customer/Red (POST)                     | RedAction                                         |\r\n| http://localhost/Customer/Orange                         | ERROR                                             |\r\n\r\n\r\n\r\n### callFile($fileStructure='%s.php',$throwOnError=true)\r\n\r\nIt calls (include) a php file using the current name of the controller\r\n\r\n* **$fileStructure** The current name of the controller. \"%s\" is the name of the current controller. Example :/Customer/Insert -\u003e calls the file Customer.php\r\n* **throwOnError** if true then it throws an error. If false then it only returns the error message.\r\n\r\n### getHeader()\r\n\r\nSyntax:\r\n\r\n\u003e getHeader($key, $valueIfNotFound = null)\r\n\r\nIt gets the current header (if any). If the value is not found, then it returns $valueIfNotFound. Note, the $key is always converted to uppercase.\r\n\r\nExample:\r\n\r\n```php\r\n$token=$this-\u003egetHeader('token','TOKEN NOT FOUND');\r\n```\r\n\r\n### getBody()\r\n\r\nSyntax:\r\n\r\n\u003e  getBody($jsonDeserialize = false, $asAssociative = true)\r\n\r\nIt gets the body of a request.\r\n\r\nExample:\r\n\r\n```php\r\n$body=$this-\u003egetBody(); // '{\"id\"=\u003e1,\"name\"=\u003ejohn}' (as string)\r\n$body=$this-\u003egetBody(true); // stdClass {id=\u003e1,name=\u003ejohn}\r\n$body=$this-\u003egetBody(true,true); // [\"id\"=\u003e1,\"name\"=\u003ejohn]\r\n```\r\n\r\n### \r\n\r\n\r\n\r\n### getCurrentUrl($withoutFilename = true)\r\n\r\nReturns the current base url without traling space, paremters or queries\r\n\r\n\u003e \u003cb\u003eNote\u003c/b\u003e: this function relies on $_SERVER['SERVER_NAME'], and  it could be modified by the end-user\r\n\r\n### getCurrentServer()\r\n\r\nIt returns the current server without trailing slash.\r\n\r\n```php \r\n$route-\u003egetCurrentServer(); // http://somedomain\r\n```\r\n\r\n### setCurrentServer($serverName)\r\n\r\nIt sets the current server name.  It is used by getCurrentUrl() and getCurrentServer().    \r\n**Note:** If $this-\u003esetCurrentServer() is not set, then it uses $_SERVER['SERVER_NAME'], and it could be modified\r\nby the user.\r\n\r\n```php \r\n$route-\u003esetCurrentServer('localhost'); \r\n$route-\u003esetCurrentServer('127.0.0.1'); \r\n$route-\u003esetCurrentServer('domain.dom'); \r\n```\r\n\r\n### getUrl($extraQuery = '',$includeQuery=false)\r\n\r\nIt gets the (full) url based in the information in the class.\r\n\r\n```php \r\n$route-\u003egetUrl(); // http://somedomain/controller/action/id\r\n$route-\u003egetUrl('id=20'); // http://somedomain/controller/action/id?id=20\r\n$route-\u003egetUrl('id=20',true); // http://somedomain/controller/action/id?id=20\u0026field=20\u0026field2=40\r\n```\r\n\r\n### url($module,$controller,$action,$id,$idparent)\r\n\r\nIt builds an url based in custom values\r\n\r\n```php \r\n$route-\u003eurl(null,\"Customer\",\"Update\",20); // Customer/Update/20\r\n```\r\n\r\n### urlFront($module,$category,$subcategory,$subsubcategory,$id)\r\n\r\nIt builds an url (front) based in custom values\r\n\r\n```php \r\n$route-\u003eurl(null,\"Daily\",\"Milk\",20); // Daily/Milk/20\r\n```\r\n\r\n### alwaysWWW($https = false)\r\n\r\nIf the subdomain is empty or different to www, then it redirect to www.domain.com.\u003cbr\u003e\r\n\u003cb\u003eNote: It doesn't work with localhost, domain without TLD (netbios) or ip domains. It is on purpose.\u003c/b\u003e\u003cbr\u003e\r\n\u003cb\u003eNote: If this code needs to redirect, then it stops the execution of the code. Usually it must be called at the\r\ntop of the code\u003c/b\u003e\r\n\r\n```php \r\n$route-\u003ealwaysWWW();  // if the domain is somedomain.dom/url, then it redirects to www.somedomain.dom/url\r\n$route-\u003ealwaysWWW(true);  // if the domain is http: somedomain.dom/url, then it redirects to https: www.somedomain.dom/url\r\n\r\n```\r\n\r\n### alwaysHTTPS()\r\n\r\nIf the page is loaded as http, then it redirects to https.    \r\n\u003cb\u003eNote: It doesn't work with localhost, domain without TLD (netbios) or ip domains. It is on purpose.\u003c/b\u003e\u003cbr\u003e\r\n\u003cb\u003eNote: If this code needs to redirect, then it stops the execution of the code. Usually it must be called at\r\nthe top of the code\u003c/b\u003e\r\n\r\n```php \r\n$route-\u003ealwaysHTTPS(); // http://somedomain.com ---\u003e https://somedomain.com\r\n$route-\u003ealwaysHTTPS(); // http://localhost ---\u003e // http://localhost\r\n$route-\u003ealwaysHTTPS(); // http://127.0.0.1 ---\u003e // http://127.0.0.1\r\n$route-\u003ealwaysHTTPS(); // http://mypc ---\u003e // http://mypc\r\n```\r\n\r\n### alwaysNakedDomain($https = false)\r\n\r\nIf the subdomain is www (example www.domain.dom) then it redirect to a naked domain domain.dom\u003cbr\u003e   \r\n\u003cb\u003eNote: It doesn't work with localhost, domain without TLD (netbios) or ip domains. It is on purpose.\u003c/b\u003e\u003cbr\u003e  \r\n\u003cb\u003eNote: If this code needs to redirect, then it stops the execution of the code. Usually,\r\nit must be called at the top of the code\u003c/b\u003e\r\n\r\n```php \r\n$route-\u003ealwaysNakedDomain();  // if the domain is www.somedomain.dom/url, then it redirects to somedomain.dom/url\r\n$route-\u003ealwaysNakedDomain(true);  // if the domain is http: www.somedomain.dom/url, then it redirects to https: somedomain.dom/url\r\n\r\n```\r\n\r\n## fields\r\n\r\n| Field           | path             | Description                                                              | Example                                                                 |\r\n|-----------------|------------------|--------------------------------------------------------------------------|-------------------------------------------------------------------------|\r\n| $argumentName   |                  | The name of the argument used by Apache .Htaccess and nginx              | $this-argumentName='req';                                               |\r\n| $base           |                  | It is the base url.                                                      | $this-\u003ebase=0;                                                          |\r\n| $type           |                  | It is the type of url (api,ws,controller or front)                       | echo $this-\u003etype; // api                                                |\r\n| $module         | {module}         | It's the current module                                                  | echo $this-\u003emodule;                                                     |\r\n| $controller     | {controller}     | It's the controller.                                                     | echo $this-\u003econtroller;                                                 |\r\n| $action         | {action}         | It's the action.                                                         | echo $this-\u003eaction;                                                     |\r\n| $id             | {id}             | It's the identifier                                                      | echo $this-\u003eid;                                                         |\r\n| $event          | {event}          | It's the event (such as \"click on button).                               | echo$this-\u003eevent;                                                       |\r\n| $idparent       | {idparent}       | It is the current parent id (if any)                                     | echo $this-\u003eidparent;                                                   |\r\n| $extra          | {extra}          | It's the event (such as \"click on button)                                | echo $this-\u003eextra;                                                      |\r\n| $category       | {category}       | The current category. It is useful for the type 'front'                  | echo $this-\u003ecategory;                                                   |\r\n| $subcategory    | {subcategory}    | The current sub-category. It is useful for the type 'front'              | echo $this-\u003esubcategory;                                                |\r\n| $subsubcategory | {subsubcategory} | The current sub-sub-category. It is useful for the type  'front'         | echo $this-\u003esubsubcategory;                                             |\r\n| $identify       |                  | It is an associative array that helps to identify the api and  ws route. | $this-\u003eidentify=['api'=\u003e'apiurl','ws'=\u003e'webservices','controller'=\u003e'']; |\r\n| $isPostBack     |                  | its true if the page is POST, otherwise false.                           | if ($this-\u003eisPostBack) { ... };                                         |\r\n| $verb           | {verb}           | The current verb, it could be GET,POST,PUT and DELETE.                   | if ($this-\u003everb) { ... };                                               |\r\n\r\nExample:\r\n```php\r\n$this-\u003eaddPath('portal/web/{controller}/{action:list}');\r\n$this-\u003efetchPath();\r\nvar_dump($this-action); // it shows the current action or the default value \"list\" if none.\r\n```\r\n\r\n## Whitelist\r\n\r\n| Field          | Description                                                                                                                                                                                                                                                                        | Example                                                                                                                                               |\r\n|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|\r\n| $allowedVerbs  | A list with allowed verbs                                                                                                                                                                                                                                                          | $this-\u003eallowedVerbs=['GET', 'POST', 'PUT', 'DELETE'];                                                                                                 |\r\n| $allowedFields | A list with allowed fields used by **callObjectEx()**                                                                                                                                                                                                                              | $this-\u003eallowedFields=['controller', 'action', 'verb', 'event', 'type', 'module', 'id'\u003cbr /\u003e, 'idparent','category', 'subcategory', 'subsubcategory']; |\r\n| setWhitelist() | It sets an associative array with the whitelist to **controller**, **action**, **category**, **subcategory**, **subsubcategory** and **module**. \u003cbr /\u003eIf not set (null default value), then it allows any entry.\u003cbr /\u003eCurrently it only work with **controller** and **category** | $this-\u003esetWhitelist('controller','Purchase','Invoice','Customer');\u003cbr /\u003e$this-\u003esetWhitelist('controller',null) // allows any controller;              |\r\n\r\n### Whitelist input.\r\nWhitelisting a method allows two operations:\r\n\r\n* To whitelist an input, for example, only allowing \"controllers\" that they are inside a list.\r\n* Also, it allows to define the case of an element.\r\n\r\nFor example:\r\n\r\n```php\r\n// Example, value not in the whitelist: someweb.dom/customer/list\r\n$this-\u003esetWhiteList('controller',['Product','Client']);\r\n$this-\u003efetch();\r\nvar_dump($this-\u003econtroller); // null or the default value\r\nvar_dump($this-\u003enotAllowed); // true (whitelist error)\r\n\r\n\r\n// Example, value in the whitelist but with the wrong case: someweb.dom/customer/list\r\n$this-\u003esetWhiteList('controller',['Customer']);\r\n$this-\u003efetch();\r\nvar_dump($this-\u003econtroller); // it shows \"Customer\" instead of \"customer\"\r\nvar_dump($this-\u003enotAllowed); // false (not error with the validation of the whitelist)    \r\n    \r\n// reset whitelist for controllers\r\n$this-\u003esetWhiteList('controller',null);        \r\n```\r\n## CLI\r\nRouteone contains a basic CLI to create and initialize the configuration.\r\nThe binary **routeonecli** is located in the vendor/bin folder\r\n\r\n![docs/cli1.jpg](docs/cli1.jpg)\r\n\r\n* Execute **routeonecli** and it will show a menu with a simple option [router]\r\n\r\n```shell\r\n./vendor/bin/routeonecli\r\n```\r\n\r\n\r\n\r\n* enter **router** and press enter. \r\n\r\n  * You can use the TAB key to autocomplete. \r\n  * You can use arrow-up and arrow-down to navigate in the options available\r\n  * If you write ?, it will show a simple help\r\n  * If you write ??, it will show a more technical help.\r\n\r\n  In the router menu, it will show the next screen:\r\n\r\n![docs/cli2.jpg](docs/cli2.jpg)\r\n\r\nPending means that the operation is pending to do, or it requires something to configure.\r\n\r\n* enter **configure**\r\n\r\n![docs/cli3.jpg](docs/cli3.jpg)\r\n\r\n* And enters the router filename without extension.\r\n* Then your developer machine. If you don't know, then press enter. \r\n* Then your developer base url. \r\n* And your production base url. If you don't have or don't know, then just use the default values\r\n\r\nOnce done, configure will be marked as \"ok\"\r\n\r\nNow, lets configure the paths\r\n\r\n* Go to paths.\r\n\r\n![docs/cli4.jpg](docs/cli4.jpg)\r\n\r\n* And it will show the next menu, add, remove or edit.\r\n* Enter **add**\r\n\r\n![docs/cli5.jpg](docs/cli5.jpg)\r\n\r\n* And enter the name of the path, example web.\r\n* And the path (check path for see the syntax of the path)\r\n* Finally, enter the name space associate with this path\r\n* Once done, you have your first path.  You can add more paths later.\r\n* Press enter to return.\r\n\r\n![docs/cli6.jpg](docs/cli6.jpg)\r\n\r\n* Now, you can generate the htaccess file, the PHP router file, load the configuration, or save the configuration entered here.\r\n* To exit press return and return.\r\n\r\n\r\n## Changelog\r\n* 2024-12-31 1.34\r\n  * updated to PHP 8.4 \r\n* 2024-03-02 1.33\r\n  * Updating dependency to PHP 7.4. The extended support of PHP 7.2 ended 3 years ago.\r\n  * Added more type hinting in the code.\r\n* 2024-01-22 1.32.1\r\n  * fixed a problem when the pattern doesn't have values, example \"contact/\" \r\n* 2024-01-22 1.32\r\n  * unit test updated. \r\n  * now route file is always called index.php\r\n  * fetchPath() considers the field that is required and the field that is optional.\r\n* 2024-01-09 1.31\r\n* 2023-11-13 1.30.1\r\n  * fixed a bug with fetch() when the url fetched is null \r\n  * updated .htaccess, so it works better with different situations.\r\n* 2023-05-08 1.30\r\n  * addPath() now allows to specify a middleware. \r\n* 2023-04-02 1.29\r\n  * [RouteOneCli] updated\r\n  * new method instance() so we could get a singleton instance using RouteOne::instance();\r\n* 2023-03-04 1.28\r\n  * Added static paths to addPath()\r\n  * callObjectEx() now allows any parameter. If the parameter is not a defined value, then it is obtained from the route.\r\n  * callObjectEx() now allows named parameter.\r\n  * callObjectEx() now allows to pass an instance and callable instead of the name of the class.\r\n  * callObjectEx() allows to filter by type of Path. By default, it does not filter value\r\n* 2023-03-04 1.27.1\r\n  * Fix a small bug when addPath() add a path that starts with \"/\". Now, the value is trimmed.\r\n* 2023-02-15 1.27\r\n  * Cleanup of the code and documentation. Deprecating old methods\r\n* 2023-02-14 1.26.4\r\n  * some bug fixed\r\n* 2023-01-27 1.26.2\r\n  * edited composer json (bin)\r\n* 2023-01-27 1.26\r\n  * callObject() marked as deprecated, however you still could use it.\r\n  * arguments of function now uses type hinting/validation\r\n  * addPath() now throws an exception if the path is empty or null.\r\n  * new method redirect()\r\n  * new CLI.\r\n* 2023-01-26 1.25\r\n  * some cleanups\r\n* 2022-03-11 1.24\r\n  * **[fix]** fix many problems when the url is null.\r\n* 2022-02-01 1.23\r\n  * [new] getRequest(), getPost(),getGet()\r\n* 2022-01-27 1.22\r\n  * [new] callObjectEx allows adding arguments to the constructor.\r\n  * [new] clearPath()\r\n  * [new] addPath()\r\n  * [new] fetchPath()\r\n  * [new] getHeader()\r\n  * [new] getBody()\r\n* 2021-04-24 1.20\r\n  * **constructor** Now it is possible to indicates the possible modules in the constructor.\r\n  * Many cleanups of the code.\r\n  *  New field called **$moduleList** including its setter and getters (by default this value is null)\r\n  *  If **$moduleList** is not null then it is used to determine if the URL is a module or not\r\n  *  New field called **$moduleStrategy** assigned in the constructor and in the setter and getters (by default this value is 'none')\r\n* 2021-02-26 1.19\r\n  * **setWhiteList()** now works with **controller** and **category**\r\n  * **setWhiteList()** also works to define the correct proper case of the elements.\r\n  * The method **callObjectEx()** allows to define the case.\r\n* 2021-02-26 1.18\r\n  * new fields **$verb** (it gets the current verb, example GET, POST, etc.)\r\n  * new whitelist elements:\r\n    * $allowedVerbs The list of allowed verbs.\r\n    * $allowedFields The list of allowed fields used by **callObjectEx()**\r\n    * $allowedControllers The list of allowed controllers. If this list is set and the controller is not in the whitelist\r\n      , then the controller is set as null\r\n  * The method **callObjectEx()** allows to use the verb. The verb is always ucfirst.\r\n    * Example $this-\u003ecallObjectEx('cocacola\\controller\\{controller}Controller','{action}Action{verb}');\r\n* 2021-02-16 1.17\r\n  * removed all @ and replaced by **isset()**. Since this library is compatible with PHP 5.6, then it doesn't use \"??\"\r\n    operators.\r\n  * **setDefaultValues()** trigger an error if it is called after fetch()\r\n* 2021-02.11 1.16.1\r\n  * fixed a problem with \"api\" and \"ws\" that it doesn't read the controller in the right position.\r\n* 2021-02-11 1.16\r\n  * Removed Travis.\r\n  * Lowered the requirement. Now, this library works in PHP 5.6 and higher (instead of PHP 7.0 and higher)\r\n  * Constructor has a new argument, it could fetch() the values\r\n  * alwaysHTTPS() has a new argument that it could return the full URL (if it requires redirect) or null\r\n  * alwaysWWW() has a new argument that it could return the full URL (if it requires redirect) or null\r\n  * alwaysNakedDomain() has a new argument that it could return the full URL (if it requires redirect) or null\r\n* 2020-06-14 1.15\r\n  * Added default values in setDefaultValues().\r\n  * Method fetch() now it unset the value.\r\n  * Fixed Method url().\r\n* 2020-06-07 1.14.2\r\n  * Bug fixed: Delete an echo (used for debug)\r\n* 2020-06-07 1.14.1\r\n  * Solved a small bug. it keeps the compatibility.\r\n* 2020-06-07 1.14\r\n  * added defcategory,defsubcategory and defsubsubcategory\r\n  * new method setIdentifyType()\r\n* 2020-04-23 1.13\r\n  * Lots of cleanups.\r\n* 2020-04-04 1.12\r\n  * added support for nginx.\r\n  * updated the documentation for .htaccess\r\n  * new method setCurrentServer()\r\n* 2020-03-27 1.11\r\n  * added alwaysNakedDomain()\r\n* 2020-03-27 1.10.1\r\n  * a small fix for alwaysHTTPS()\r\n* 2020-03-27 1.10\r\n  * added method alwaysHTTPS() and alwaysWWW()\r\n* 2020-02-15 1.9\r\n  * added new arguments to callObject()\r\n  * new method callObjectEx()\r\n* 2020-02-03 1.8\r\n  * new method getNonRouteUrl()\r\n  * new method setExtra()\r\n  * new method isPostBack()\r\n  * new method setIsPostBack()\r\n  * Some fixes for getUrl() \r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feftec%2Frouteone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feftec%2Frouteone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feftec%2Frouteone/lists"}