Skip to content

Commit

Permalink
- Major changes
Browse files Browse the repository at this point in the history
- Foreign keys between tables
- Cronjob fill available namespaces for your request
  • Loading branch information
daycry committed Aug 24, 2022
1 parent 3b249b5 commit 6dbf11f
Show file tree
Hide file tree
Showing 50 changed files with 981 additions and 612 deletions.
63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Rest Server with Doctrine for Codeigniter 4
[![GitHub stars](https://img.shields.io/github/stars/daycry/restserver)](https://packagist.org/packages/daycry/restserver)
[![GitHub license](https://img.shields.io/github/license/daycry/restserver)](https://github.com/daycry/restserver/blob/master/LICENSE)

## **Version 7**

## This version breaks compatibility with previous versions, since it contains new automated features, restructuring of the database with new foreign keys, so if you update, check that the names of the tables are in the plural.

## Installation via composer

Use the package with composer install
Expand All @@ -37,6 +41,7 @@ Run command:

> php spark restserver:publish
> php spark settings:publish
> php spark cronjob:publish
> php spark jwt:publish

This command will copy a config file to your app namespace.
Expand Down Expand Up @@ -239,7 +244,7 @@ You can customize the requests independently using the `petition` table.

Fiels | Value | Options | Desctiption
-------- | ------------- | ------- | -----------
`controller` | `\App\Controllers\Auth` | | Use this field to configure the controller in namespace format
`namespace_id` | | | This field contains the identifier of the **ws_namespaces** table, this table stores the namespaces of the classes, for example `\App\Controllers\Auth`
`method`| `login` | | Use this field to configure the method of controller
`http`| `post` | `get`,`post`,`put`,`patch`, `options` | Use this field to configure the method of controller
`auth`| `bearer` | `false`,`basic`,`digest`,`bearer` | Use this field to configure the autentication method
Expand All @@ -248,6 +253,62 @@ Fiels | Value | Options | Desctiption
`time`| `null` | `null`,`1`,`15` | This field is used to know how often the request limit is reset ( Time in seconds Example: 3600 -> In this case you can do {limit} request in 3600 seconds)
`level`| `null` | `null`,`1`,`10` | Use this field to indicate the level of permissions in the request, if the token has level 1 and the request has level 3, you will not be able to make the request

You can fill the **ws_namespaces** automatically with a command.

```php
<?php

php spark restserver:discover
```

This command search class in the namespace o namespaces that you want.
You can set this namespaces in the **RestServer.php** config file.

```php
<?php

/**
*--------------------------------------------------------------------------
* Cronjob
*--------------------------------------------------------------------------
*
* Set to TRUE to enable Cronjob for fill the table petitions with your API classes
* $restNamespaceScope \Namespace\Class or \Namespace\Folder\Class or \Namespace example: \App\Controllers
*
* This feature use Daycry\CronJob vendor
* for more information: https://github.com/daycry/cronjob
*
*/
public string $restApiTable = 'ws_apis';
public string $restNamespaceTable = 'ws_namespaces';
public array $restNamespaceScope = ['\App\Controllers', '\Api\Controllers'];
```

Or creating a cronjob tasks editing **CronJob.php** config file like this.

```php
<?php

/*
|--------------------------------------------------------------------------
| Cronjobs
|--------------------------------------------------------------------------
|
| Register any tasks within this method for the application.
| Called by the TaskRunner.
|
| @param Scheduler $schedule
*/
public function init(Scheduler $schedule)
{
$schedule->command('restserver:discover')->named('discoverRestserver')->dayly();
or
$schedule->command('restserver:discover')->named('discoverRestserver')->dayly('11:30 am');
}
```

More information about cronjob: https://github.com/daycry/cronjob

## RESPONSE

The default response is in `json` but you can change to `xml` in the headers.
Expand Down
89 changes: 0 additions & 89 deletions UPDATE-v3.md

This file was deleted.

6 changes: 4 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
</include>
<exclude>
<directory suffix=".php">./src/Config</directory>
<directory suffix=".php">./src/Entities</directory>
<directory suffix=".php">./src/Commands</directory>
<directory suffix=".php">./src/Database</directory>
<directory suffix=".php">./src/Libraries/User</directory>
<directory suffix=".php">./src/Interfaces</directory>
<file>./src/Libraries/CheckIp.php</file>
<file>./src/Libraries/Utils.php</file>
<file>./src/Exceptions/UserException.php</file>
</exclude>
<report>
Expand All @@ -43,14 +45,14 @@
<junit outputFile="build/logs/logfile.xml"/>
</logging>
<php>
<server name="app.baseURL" value="http://example.com/"/>
<server name="app.baseURL" value="https://vendor.local/"/>
<env name="app.appTimezone" value="Europe/Madrid" force="true"/>
<!-- Directory containing phpunit.xml -->
<const name="HOMEPATH" value="./"/>
<!-- Directory containing the Paths config file -->
<const name="CONFIGPATH" value="./vendor/codeigniter4/framework/app/Config/"/>
<!-- Directory containing the front controller (index.php) -->
<const name="PUBLICPATH" value="./public/"/>
<const name="PUBLICPATH" value="./vendor/codeigniter4/framework/public/"/>
<!-- Database configuration -->
<!-- <env name="database.tests.hostname" value="localhost" force="true"/> -->
<env name="database.default.database" value="web_service_tests" force="true"/>
Expand Down
157 changes: 157 additions & 0 deletions src/Commands/DiscoverClasses.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<?php

namespace Daycry\RestServer\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use CodeIgniter\Config\BaseConfig;
use \Daycry\RestServer\Traits\Schema;
use DateTime;

class DiscoverClasses extends BaseCommand
{
use Schema;

protected $group = 'Rest Server';
protected $name = 'restserver:discover';
protected $description = 'Discover classes from namespace to import in database.';

protected Datetime $timeStart;
protected BaseConfig $config;
protected array $allClasses = [];

public function run(array $params)
{
$this->timeStart = ( new DateTime('now'))->modify('-1 second');

$this->config = config('RestServer');

if( !empty($this->config->restNamespaceScope ) )
{
$finderConfig = config('ClassFinder');
$finderConfig->finder['files'] = false;

$api = $this->_checkApiModel();

foreach( $this->config->restNamespaceScope as $namespace )
{
//remove "\" for search in class-finder
$namespace = ( mb_substr($namespace, 0, 1) == '\\' ) ? mb_substr($namespace, 1) : $namespace;

$classes = (new \Daycry\ClassFinder\ClassFinder($finderConfig))->getClassesInNamespace($namespace);
if( $classes )
{
foreach( $classes as $class )
{
\array_push($this->allClasses, '\\' . $class);

$methods = $this->_getMethodsFromCLass($class);

foreach( $methods as $key => $value )
{
if( strpos( $value, '__' ) !== false )
{
unset($methods[$key]);
}
}

$class = ( mb_substr($class, 0, 1) !== '\\' ) ? '\\' . $class : $class;
$this->_checkClassNamespace($api, $class, $methods);
}

unset($classes);
}
}

//removing obsolet namespaces
$namespaceModel = new \Daycry\RestServer\Models\NamespaceModel();
$namespaces = ($api->{$this->config->restNamespaceTable}) ? $api->{$this->config->restNamespaceTable} : [];
foreach( $namespaces as $n )
{
if(!\in_array( $n->controller, $this->allClasses))
{
$requestModel = new \Daycry\RestServer\Models\PetitionModel();
$availableRequest = ($n->{$this->config->configRestPetitionsTable}) ? $n->{$this->config->configRestPetitionsTable} : [];

foreach( $availableRequest as $r )
{
$requestModel->delete($r->id);
}
$namespaceModel->delete($n->id);
}
}
}

CLI::write( '**** FINISHED. ****', 'white', 'green' );
}

private function _checkApiModel() :?\Daycry\RestServer\Entities\ApiEntity
{
$apiModel = new \Daycry\RestServer\Models\ApiModel();
$api = $apiModel->setSchema(self::getSchema())->where('url', site_url())->first();

if( !$api )
{
$api = new \Daycry\RestServer\Entities\ApiEntity();
$api->fill( array('url' => site_url()) );
$apiModel->save($api);
$api->id = $apiModel->getInsertID();
}else{
$api->fill(array( 'checked_at' => (new DateTime('now'))->format('Y-m-d H:i:s') ));
$apiModel->save($api);
}

return $api;
}

private function _getMethodsFromCLass($namespace) :array
{
$methods = get_class_methods($namespace);
return ( $methods ) ? $methods : [];
}

private function _checkClassNamespace( \Daycry\RestServer\Entities\ApiEntity $api, string $class, array $methods = [] )
{
$namespaceModel = new \Daycry\RestServer\Models\NamespaceModel();

$found = false;
$namespaces = $api->{$this->config->restNamespaceTable};
if( $namespaces )
{
foreach( $namespaces as $namespace )
{
$namespace->fill(array( 'checked_at' => (new DateTime('now'))->format('Y-m-d H:i:s') ));
$namespaceModel->save($namespace);

if( $namespace->controller == $class )
{
$found = true;
break;
}
}
unset($namespaces);
}

if( !$found)
{
$namespace = new \Daycry\RestServer\Entities\NamespaceEntity();
$namespace = $namespace->setController($class)->setMethods($methods);
$namespace->api_id = $api->id;
$namespaceModel->save($namespace);
}else{
$availableRequest = ($namespace->{$this->config->configRestPetitionsTable}) ? $namespace->{$this->config->configRestPetitionsTable} : [];
$requestModel = new \Daycry\RestServer\Models\PetitionModel();

foreach( $availableRequest as $request )
{
if( $request->method === null || \in_array( $request->method, $methods) )
{
$request->checked_at = (new DateTime('now'))->format('Y-m-d H:i:s');
$requestModel->save( $request );
}else{
$requestModel->delete( $request->id );
}
}
}
}
}
Loading

0 comments on commit 6dbf11f

Please sign in to comment.