Skip to content

Commit

Permalink
Jusk works
Browse files Browse the repository at this point in the history
  • Loading branch information
zhwei committed Aug 22, 2020
0 parents commit dd4621e
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "composer" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
directory: "/"
schedule:
interval: "daily"
41 changes: 41 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: tests

on:
push:
branches:
- master
pull_request:

jobs:
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
php: [7.3, 7.4]
laravel: ['6.0', '7.0']

name: P${{ matrix.php }} - L${{ matrix.laravel }}

steps:
- name: Checkout code
uses: actions/[email protected]

- name: Cache dependencies
uses: actions/cache@v2
with:
path: ~/.composer/cache/files
key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}

- name: Setup PHP
uses: shivammathur/[email protected]
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick
coverage: none

- name: Install dependencies
run: composer require "illuminate/support=^${{ matrix.laravel }}" --prefer-dist --no-interaction -vvv

- name: Execute tests
run: vendor/bin/phpunit --verbose
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/vendor
/composer.lock
/.phpunit.result.cache
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Laravel Autowire Kit

## Usage

1. Composer

```bash
composer require zhwei/laravel-autowire
```

2. Register Service Provider (Lumen only)

```php
$app->register(\Zhwei\LaravelAutowire\AutowireServiceProvider::class);
```

3. Autowire

Any class implemented the `Zhwei\LaravelAutowire\AutowireAble` interface will trigger auto-wire after container resolution.

```php
class HelloController implements Zhwei\LaravelAutowire\AutowireAble
{
/**
* @autowire
* @var \Illuminate\Contracts\Cache\Factory
*/
protected $cache;

public function hello()
{
return $this->cache->store()->get('hello');
}
}
```

or trigger by your self:

```php
$hello = new HelloController();
Zhwei\LaravelAutowire\AutowireInjector::inject(app(), $hello);
```
41 changes: 41 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "zhwei/laravel-autowire",
"description": "Laravel Autowire Kit",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "zhwei",
"email": "[email protected]"
}
],
"require": {
"php": "^7.2",
"illuminate/support": "^6.0 || ^7.0",
"php-di/phpdoc-reader": "^2.1"
},
"autoload": {
"psr-4": {
"Zhwei\\LaravelAutowire\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Zhwei\\LaravelAutowireTests\\": "tests/"
}
},
"config": {
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Zhwei\\LaravelAutowire\\AutowireServiceProvider"
]
}
},
"require-dev": {
"laravel/laravel": "^7.25",
"phpunit/phpunit": "^9.3"
}
}
28 changes: 28 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http:https://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Tests">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>
7 changes: 7 additions & 0 deletions src/AutowireAble.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Zhwei\LaravelAutowire;

interface AutowireAble
{
}
42 changes: 42 additions & 0 deletions src/AutowireInjector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Zhwei\LaravelAutowire;

use Illuminate\Contracts\Container\Container;
use PhpDocReader\PhpDocReader;

class AutowireInjector
{
private const TOKEN = '@autowire';

public static function inject(Container $container, object $instance)
{
$rfo = new \ReflectionObject($instance);
if (!$properties = $rfo->getProperties()) {
return;
}

static $reader;
$reader || $reader = new PhpDocReader();

foreach ($properties as $property) {
if (strpos($property->getDocComment(), self::TOKEN) === false) {
continue;
}

// 设置可见性,方便下面读写
if ($property->isPublic() === false) {
$property->setAccessible(true);
}

// 如果有值,则跳过注入
if ($property->getValue($instance) !== null) {
continue;
}

if ($class = $reader->getPropertyClass($property)) {
$property->setValue($instance, $container->make($class));
}
}
}
}
15 changes: 15 additions & 0 deletions src/AutowireServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Zhwei\LaravelAutowire;

use Illuminate\Support\ServiceProvider;

class AutowireServiceProvider extends ServiceProvider
{
public function boot()
{
$this->app->afterResolving(AutowireAble::class, function ($instance) {
AutowireInjector::inject($this->app, $instance);
});
}
}
36 changes: 36 additions & 0 deletions tests/AutowireTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Zhwei\LaravelAutowireTests;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Testing\TestCase;
use Zhwei\LaravelAutowire\AutowireServiceProvider;

class AutowireTest extends TestCase
{
public function testContainer()
{
/** @var ExampleA $a */
$a = app(ExampleA::class);
self::assertInstanceOf(ExampleB::class, $a->getPrivateProperty());
self::assertInstanceOf(ExampleB::class, $a->getProtectedProperty());
self::assertInstanceOf(ExampleB::class, $a->getPublicProperty());
self::assertInstanceOf(ExampleB::class, $a::getPrivateStatic());
self::assertInstanceOf(ExampleB::class, $a::getProtectedStatic());
self::assertInstanceOf(ExampleB::class, $a::getPublicStatic());
self::assertNull($a->getPrivatePropertyNotWire());

$a::getPublicStatic()->value = 'overwrite';

$aa = app(ExampleA::class);
self::assertSame('overwrite', $aa::getPublicStatic()->value);
}

public function createApplication()
{
$app = require __DIR__ . '/../vendor/laravel/laravel/bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
$app->register(AutowireServiceProvider::class);
return $app;
}
}
105 changes: 105 additions & 0 deletions tests/ExampleA.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Zhwei\LaravelAutowireTests;

use Zhwei\LaravelAutowire\AutowireAble;

class ExampleA implements AutowireAble
{
/**
* @var ExampleB
*/
private $privatePropertyNotWire;

/**
* @autowire
* @var ExampleB
*/
private $privateProperty;

/**
* @autowire
* @var ExampleB
*/
protected $protectedProperty;

/**
* @autowire
* @var ExampleB
*/
public $publicProperty;

/**
* @autowire
* @var ExampleB
*/
private static $privateStatic;

/**
* @autowire
* @var ExampleB
*/
protected static $protectedStatic;

/**
* @autowire
* @var ExampleB
*/
public static $publicStatic;

/**
* @return ExampleB
*/
public function getPrivateProperty(): ExampleB
{
return $this->privateProperty;
}

/**
* @return ExampleB
*/
public function getProtectedProperty(): ExampleB
{
return $this->protectedProperty;
}

/**
* @return ExampleB
*/
public function getPublicProperty(): ExampleB
{
return $this->publicProperty;
}

/**
* @return ExampleB
*/
public static function getPrivateStatic(): ExampleB
{
return self::$privateStatic;
}

/**
* @return ExampleB
*/
public static function getProtectedStatic(): ExampleB
{
return self::$protectedStatic;
}

/**
* @return ExampleB
*/
public static function getPublicStatic(): ExampleB
{
return self::$publicStatic;
}

/**
* @return ExampleB
*/
public function getPrivatePropertyNotWire()
{
return $this->privatePropertyNotWire;
}
}
8 changes: 8 additions & 0 deletions tests/ExampleB.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Zhwei\LaravelAutowireTests;

class ExampleB
{
public $value = 'default';
}

0 comments on commit dd4621e

Please sign in to comment.