GithubHelp home page GithubHelp logo

ryannerd / willow Goto Github PK

View Code? Open in Web Editor NEW
18.0 6.0 4.0 516 KB

Willow Framework for quickly creating ORM/RESTful APIs

Home Page: https://www.notion.so/ryannerd/Get-Started-bf56317580884ccd95ed8d3889f83c72

License: MIT License

PHP 93.18% Twig 6.82%
restful-api crud-api framework-php crud

willow's Introduction

๐ŸŒณ Willow Framework ๐ŸŒณ

License: MIT

willow Willow is a type a girl who is beautiful and amazing and is kinda a special person and loved by everyone around her most willows can be your best of friends she's up for anything and she's loves anything fun you throw at her...

~ Urban Dictionary

For developers, Willow is an opinionated PHP framework used to quickly create CRUD based RESTful APIs.

Willow is a marriage ๐Ÿ’’ between Slim and Eloquent ORM with Robo as your wedding planner.

For instructions and getting started see the Willow Framework User Guide

Willow works best as a framework in this situation:

  • You need to quickly spin up a RESTful datacentric API
  • You have defined your database with your tables already in place
  • You are just starting your project and need to hit the ground running

๐Ÿ“ƒ Requirements

  • PHP 7.4+ (Willow 3.0+)
  • Databases:
    • MySQL 5.6+
    • SQLite3
    • Postgres (untested)
    • MSSQL (untested)
  • Composer (For Willow to work best this must be installed globally)
Notes
Willow will work on Windows only if running in the Windows Subsystem for Linux (WSL)
Previous versions of Willow are no longer supported (sorry I don't have the bandwidth to support these)

๐Ÿ’พ Installation

To install Willow run:

composer create-project --ignore-platform-reqs ryannerd/willow:^3 [your-project-name]
cd [your-project-name]

This will create a skeleton Willow project. Willow tries to symlink to robo You can then use Willow (robo) commands to build your app.

Demo

./willow sample

The result in your browser should look something like this:

{
  "authenticated": true,
  "success": true,
  "status": 200,
  "data": {
    "id": "hello-world"
  },
  "missing": [ ],
  "message": "Sample test",
  "timestamp": 1556903905
}

Willow (robo) Commands

# Documentation and demo
./willow docs   # bring up the documentation web page
./willow list   # list all available Willow commands
./willow sample # launch the sample API in a web browser
./willow banner # show the Willow introductory banner

# Willow core commands
./willow make   # Connects to your database and builds routes, controllers, models, actions, etc.
./willow reset  # Resets the project back to factory defaults
./willow eject  # Removes the sample artifacts from the project

# Database commands
./willow tables  # list all the tables in the database
./willow details # Show details (column names and types) of a selected table

Contributing

Do this:

  1. Fork this repo
  2. Make changes on your fork
  3. Push a PR

Note: the main branch isn't master it's 3.x which is where you want to push your PR.

Special thanks to:

The Slim Framework

Illuminate / Eloquent ORM

Willow icon made by Freepik from www.flaticon.com is licensed by CC 3.0 BY

willow's People

Contributors

ryannerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

willow's Issues

./willow eject command not working

Error message:

PHP Warning:  unlink(/home/ryan/Projects/test-willow/app/Robo/Plugin/Commands/../../../Controllers/Sample):
 Is a directory in /home/ryan/Projects/test-willow/app/Robo/Plugin/Commands/MakeCommands.php on line 259

Add Model Doc block properties and FIELDS const when generating from template

Example:

/**
 * @property integer $Id
 * @property integer $ResidentId
 * @property string $Drug
 * @property string $Strength
 * @property string $Barcode
 * @property string $Directions
 * @property string $Notes
 * @property integer $FillDateDay
 * @property integer $FillDateMonth
 * @property integer $FillDateYear
 * @property boolean $OTC
 * @property DateTime $Created
 * @property DateTime $Updated
 * @property DateTime $deleted_at
 *
 * @mixin Builder
 */
class Medicine extends ModelBase
{
    public const FIELDS = [
        'Id' => 'integer',
        'ResidentId' => 'integer',
        'UserId' => 'integer',
        'Drug' => 'string',
        'Strength' => 'string',
        'Barcode' => 'string',
        'Directions' => 'string',
        'Notes' => 'string',
        'FillDateMonth' => 'tinyint',
        'FillDateDay' => 'tinyint',
        'FillDateYear' => 'integer',
        'OTC' => 'boolean',
        'Created' => 'datetime',
        'Updated' => 'datetime',
        'deleted_at' => 'datetime'
    ];
}

Test Willow with other databases

In theory the following databases are supported (by Eloquent ORM):

  • MySQL/MariaDB
  • MS SQL
  • SQLite
  • Postgres

Need some help testing these.

Revamp WriteValidatorBase

<?php
declare(strict_types=1);

namespace Willow\Controllers;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Respect\Validation\Validator as V;
use Willow\Middleware\ResponseBody;

abstract class WriteValidatorBase
{
    public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
    {
        $responseBody = $this->processValidation($request->getAttribute('response_body'));

        // If there are any missing or required data points then we short circuit and return invalid request.
        if ($responseBody->hasMissingRequiredOrInvalid()) {
            $responseBody = $responseBody
                ->setStatus(ResponseBody::HTTP_BAD_REQUEST)
                ->setMessage('Missing or invalid request');
            return $responseBody();
        }

            return $handler->handle($request);
    }

    /**
     * You should override this function to perform the validations
     * @param ResponseBody $responseBody
     * @return ResponseBody
     */
    protected function processValidation(ResponseBody $responseBody): ResponseBody {
        return $responseBody;
    }

    /**
     * Default processValidation() for generic validations
     * @param ResponseBody $responseBody
     * @param array $fields
     * @return ResponseBody
     */
    protected function defaultValidation(ResponseBody $responseBody, array $fields): ResponseBody {
        $parsedRequest = $responseBody->getParsedRequest();
        // Iterate all the model fields
        foreach($fields as $field => $dataType) {
            $protectedField = $dataType[0] === '*';
            // Is the model field NOT in the request?
            if (!V::key($field)->validate($parsedRequest)) {
                // Any dataType proceeded with an * are protected fields and can not be changed (e.g. password_hash)
                if ($protectedField) {
                    continue;
                }
                // If the request is missing this field so register it as optional
                $responseBody->registerParam('optional', $field, $dataType);
            } else {
                // If Datatype is proceeded with an * it means the field is protected and can not be changed (e.g. password_hash)
                if ($protectedField) {
                    $responseBody->registerParam('invalid', $field, null);
                }
                // Don't allow emoji characters -- this prevents SQL Errors
                if ($dataType === 'string') {
                    $fieldValue = $parsedRequest[$field];
                    if (V::notEmpty()->validate($fieldValue) && !V::notEmoji()->validate($fieldValue)) {
                        $responseBody->registerParam('invalid', $field, 'alpha-numeric. Value given: ' . $fieldValue);
                    }
                }
            }
        }
        return $responseBody;
    }
}

Unit Tests

Add PHPUnit as a dev dependency and create some unit tests:

Middleware:

  • JsonBodyParser
  • ResponseBody / ResponseBodyFactory
  • Validate

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.