laravel-commode 的通用助手/实用工具/服务

dev-master 2015-05-21 00:20 UTC

This package is not auto-updated.

Last update: 2024-09-14 15:52:55 UTC


README

#Commode: Common

Build Status Code Climate Coverage Status

laravel-commode/common 是所有 commode 包的通用 utils/services 包。其中一些只应在 laravel-commode 内部使用,而另一些可能对开发有用。


####内容

##安装

您可以使用 composer 安装 laravel-commode/common

"require": {
    "laravel-commode/common": "dev-master"
}

要启用包,您需要注册 LaravelCommode\Common\CommodeCommonServiceProvider 服务提供者。实际上,注册 CommodeCommonServiceProvider 有两种方式 - 第一种适用于所有服务提供者 - 您只需将其添加到 Laravel 应用程序配置的提供者列表中

<?php
    // ./yourLaravelApplication/app/config/app.php
    return [
        // ... config code
        'providers' => [
            // ... providers
            'LaravelCommode\Common\CommodeCommonServiceProvider'
        ]
    ];

或者,您可以开始使用 GhostService 服务提供者,只需实现一个,因为每个 GhostService 服务提供者都会检查 CommodeCommonServiceProvider 是否已注册,如果没有,则自动注册它。例如,它可以是您的中央应用程序服务提供者,它会加载依赖的服务提供者

<?php namespace MyApp\ServiceProviders;

    use LaravelCommode\Common\GhostService;

    class ApplicationServiceProvider extends GhostService
    {

        // your ghost service code


        public function uses()
        {
            return [
                'MyApp\ServiceProviders\DomainLogicServiceProvider', // your domain logic service provider,
                'MyApp\ServiceProviders\DALServiceProvider', // your data access layer service provider,
                // ... e.t.c.
            ];
        }
    }

然后,在您的配置中,您可以简单地添加 ApplicationServiceProvider 而无需提及 CommodeCommonServiceProviderDomainLogicServiceProvider 等等...

<?php
    // ./yourLaravelApplication/app/config/app.php
    return [
        // ... config code
        'providers' => [
            // ... providers,
            /**
            /* will load all dependent services returned from uses()
            /* method and CommodeCommonServiceProvider as well
            **/
            'MyApp\ServiceProviders\ApplicationServiceProvider'
        ]
    ];

##GhostService

GhostService 是一个继承自 Illuminate\Support\ServiceProvider 的类,具有一些有用的功能。要创建一个鬼服务,您只需扩展 LaravelCommode\Common\GhostService 类并实现两个基本受保护方法:registering()launching()

<?php namespace MyApp\ServiceProviders;

    use LaravelCommode\Common\GhostService;

    class YourServiceProvider extends GhostService
    {
        /**
        *   Will be triggered when the app is booting
        **/
        protected function launching() { }

        /**
        *   Triggered when service is being registered
        **/
        protected function registering() { }
    }

GhostService 的一项最有用的功能是它加载依赖的服务提供者。当您的应用程序配置文件很大或者您正在开发自定义包,并且不希望滥用后续的开发者/用户实现依赖的服务提供者时,这可能很有用。
对于服务自动加载,您可以通过重写方法 public function uses() 来实现,该方法必须返回服务提供者名称的数组。如果已加载依赖的服务提供者,则将在加载链中忽略它。

<?php namespace MyApp\ServiceProviders;

    use LaravelCommode\Common\GhostService;

    class YourServiceProvider extends GhostService
    {
        public function uses()
        {
            return [
                'MyApp\ServiceProviders\DALServiceProvider',
                'Illuminate\Hashing\HashServiceProvider',
                'Vendor\Package\UsefulServiceProvider'
            ];
        }

        /**
        *   Will be triggered when the app is booting
        **/
        protected function launching() { }

        /**
        *   Triggered when service is being registered
        **/
        protected function registering() { }
    }

对于那些在 'Laravel 中的 Facades' 主题上提出很多批评的 Laravel 用户,GhostService 提供者的解析方法 protected function with($resolvable, callable $do)。该方法期望 $resolvable 参数为 stringarray 的字符串,其中包含已注册在 IoC 容器中或在运行时可以解析的绑定,而 $do 参数为 callable

<?php namespace MyApp\ServiceProviders;

    use LaravelCommode\Common\GhostService;

    class YourServiceProvider extends GhostService
    {
        /**
        *   @var Illuminate\View\Factory|null
        */
        protected $viewFactory = null;

        public function uses()
        {
            return [
                'MyApp\ServiceProviders\DALServiceProvider',
                'Illuminate\Hashing\HashServiceProvider',
                'Vendor\Package\UsefulServiceProvider'
            ];
        }

        /**
        *   Will be triggered when the app is booting
        **/
        protected function launching() { }

        private function doSomethingWithHash(\Illuminate\Hashing\BcryptHasher $hash)
        {
            //do something with $hash
        }

        private function doSomethingWithUseful(\Vendor\UsefulPackage\IUsefulBoundInterface $useful)
        {
            //do something with $useful
        }

        /**
        *   Triggered when service is being registered
        **/
        protected function registering()
        {
            $usings = ['hash', \Vendor\UsefulPackage\IUsefulBoundInterface::class, 'view'];

            $this->with($usings, function ($hash, $useful, $view)
            {
                $this->doSomethingWithHash($hash);
                $this->doSomethingWithUseful($useful);
                $this->viewFactory = $view;
            });
        }
    }

如果您的服务提供者需要注册一个 facade 或 facade 列表,您可以通过重写 protected $aliases = []; 并将其分配给一个数组来实现,其中键是 facade 名称,值是绑定的 facade 类名。

    protected $aliases = [
        'MyFacade' => \MyVendor\MyPackage\Facades\MyFacade::class
    ];

Resolver

Resolver 是一个小巧但有用的类,用于构建灵活的或需要解析的东西。它可以通过 CommodeResolver facade 使用,或者如果您不喜欢 facade,您可以在 IoC 容器中通过别名 "commode.common.resolver" 或以 new \LaravelCommode\Common\Resolver\Resolver($laravelApplication) 的形式初始化新实例找到它。

例如,假设您有一个安全模块的结构,例如 ISecurityUser,它绑定到您配置的 eloquent 身份验证模型。

<?php namespace App\System\Security\Abstractions;

    interface ISecurityUser
    {
        public function hasPermission($permission);
        public function hasPermissions(array $permissions);
    }

<?php namespace App\DAL\Concrete\Eloquent\Models;

    use Illuminate\Database\Eloquent\Model;

    class Account extends Model implements ISecurityUser
    {
        /* your eloquent model code */
    }

<?php namespace App\ServiceProviders;

    use LaravelCommode\Common\GhostService\GhostService;
    use MyApp\System\Security\Abstractions\ISecurityUser;

    class ACLServiceProvider extends GhostService
    {
        public function launching() {}

        public function registering()
        {
            $this->app->bind(ISecurityUser::class, function ($app)
            {
                return app('auth')->user(); // note that returned value might be null
            });
        }
    }

Resolver 可以解析闭包和类方法,或将它们转换为可解析的闭包。下面是使用它的一个示例。

### Resolver 和闭包

<?php
    use App\System\Security\Abstractions\ISecurityUser;

    $closureThatNeedsToBeResolved = function ($knownParameter1, $knownParameterN, ISecurityUser $needsToBeResolved = null)
    {
        return func_get_args();
    };

    $resolver = new \LaravelCommode\Common\Resolver\Resolver(); // or app('commode.resolver');

    $knownParameter1 = 'Known';
    $knownParameter2 = 'Parameter';

    /**
    *   Resolving closure and running it
    **/
    $result = $resolver->closure($closureThatNeedsToBeResolved, [$knownParameter1, $knownParameter2]);
    $resultClosure = $resolver->makeClosure($closureThatNeedsToBeResolved);

    var_dump(
        $result, $resultClosure($knownParameter1, $knownParameter2),
        $result === $resultClosure($knownParameter1, $knownParameter2)
    );

    // outputs
    //  array (size=3)
    //      0 => string 'Known' (length=5)
    //      1 => string 'Parameter' (length=9)
    //      2 =>  object(MyApp\DAL\Concrete\Eloquent\Models\Account)
    //  array (size=3)
    //      0 => string 'Known' (length=5)
    //      1 => string 'Parameter' (length=9)
    //      2 =>  object(MyApp\DAL\Concrete\Eloquent\Models\Account)
    //  boolean true

### Resolver 和类方法

<?php
    use App\System\Security\Abstractions\ISecurityUser;

    class SomeClass
    {
        public function methodThatNeedsToBeResolved($knownParameter1, $knownParameterN, ISecurityUser $needsToBeResolved = null)
        {
            return func_get_args();
        }
    }

    $resolver = new \LaravelCommode\Common\Resolver\Resolver(); // or app('commode.resolver');
    $someClass = new SomeClass();

    $knownParameter1 = 'Known';
    $knownParameter2 = 'Parameter';

    $result = $resolver->method($someClass, 'methodThatNeedsToBeResolved', [$knownParameter1, $knownParameter2]);
                //  or ->method(SomeClass::class, ..., ...) for calling static method or resolving class through
                //                                          app IOC

    $resultClosure = $resolver->methodToClosure($someClass, 'methodThatNeedsToBeResolved');
                //  or ->method(SomeClass::class, ..., ...) for calling static method or resolving class through
                //                                          app IOC

    var_dump(
        $result, $resultClosure($knownParameter1, $knownParameter2),
        $result === $resultClosure($knownParameter1, $knownParameter2)
    );

    // outputs
    //  array (size=3)
    //      0 => string 'Known' (length=5)
    //      1 => string 'Parameter' (length=9)
    //      2 =>  object(MyApp\DAL\Concrete\Eloquent\Models\Account)
    //  array (size=3)
    //      0 => string 'Known' (length=5)
    //      1 => string 'Parameter' (length=9)
    //      2 =>  object(MyApp\DAL\Concrete\Eloquent\Models\Account)
    //  boolean true

Controller

laravel-commode/common 提供了一个简单的控制器,它并没有太多改变默认控制器,但它提供了在 Laravel 4.0-4.2 版本中常常在 StackOverflow 等资源上被提问的功能。

LaravelCommode\Common\Controllers\CommodeController 提供了可解析的方法调用,可以将 AJAX 调用分离到不同的方法中,或者完全禁止 AJAX 调用。

默认情况下,方法解析器是启用的,但你可以通过重写 protected $resolveMethods 并将其设置为 protected $resolveMethods = false; 来禁用它。当安装了 laravel-commode/viewmodel 包时,这个功能非常有用。示例

<?php namespace MyApp\Domain\Areas\Administrator\Controllers;

    use LaravelCommode\Common\Controllers\CommodeController;
    use LaravelCommode\ViewModel\Interfaces\IRequestBag;

    class AccountController extends CommodeController
    {
        /* some controller code */

        protected function returnBack()
        {
            return \Redirect::to(\URL::current())->withInput();
        }

        public function getSearch(IRequestBag $searchParams)
        {
            $collection = $this->accountService->search($searchParams->toArray());
            return \View::make('Administrator::account.search', compact('collection'));
        }

        public function postEdit($id, AccountViewModel $viewModel)
        {
            if (!$viewModel->isValid())
            {
                return $this->returnBack()->withErrors($viewModel->getValidator());
            }

            if (!$this->accountStrategy->updateFromViewModel($viewMode))
            {
                return $this->returnBack()->with('error.strategy', $this->accountStrategy->getState());
            }

            return \Redirect::action(__CLASS__.'@getIndex');
        }
    }

默认情况下,AJAX 分离调用是禁用的,但你可以通过重写 protected $separateRequests 并将其设置为 protected $separateRequests = true; 来启用它。要定义一个 AJAX 方法,只需在方法名前添加 'ajax' 前缀。示例

<?php namespace MyApp\Domain\Areas\Site\Controllers;

    use LaravelCommode\ViewModel\Interfaces\IRequestBag;

    class PostsController extends CommodeController
    {
        protected $separateRequests = true;

        /* some controller code */

        /**
        *   Returns JSONable results when ajax is triggered
        **/
        public function ajaxgetLatest($lastId = null)
        {
            return $this->postService->getLatest($lastId);
        }

        /**
        *   Returns same collection as ::ajaxgetLatest() method,
        *   but wraps it with view
        **/
        public function getLatest()
        {
            return \View::make('Site::posts.list', [
                'posts' => $this->ajaxgetLatest()
            ]);
        }
    }

你可以通过重写 protected $allowAjax 并将其设置为 protected $allowAjax = false; 来禁止 AJAX 调用——这将返回 404 HTTP 状态码。