Laravel Composer Package 开发实战 toastr-for-laravel5

本文最早发表于本人博客: Laravel Composer Package 开发实战 toastr-for-laravel5

在Laravel的文档中有Package Development,对于入门开发人员来说还是比较抽象,因为开发一个包需要了解 Service Providers,Service Providers 和 Facade 已经够抽象的了对刚接触Laravel的开发人员来说,所以我来写一个简单的Laravel 包开发的实例教程吧。

toastr.js是一个很方便的通知效果,最近刚发布了laravel 5.2,所以就来开发一个toastr for laravel 5的包吧,主要用toastr结合laravel的flash session来实现页面的一次性消息提醒,其实这个在我们日常开发中页面操作提醒还是很常用到的业务。

一般的laravel 包开发过程是这样的,开发好以后打包push到gitlab,然后在packagist上提交,下面我们就来一步一步实现这个过程。

1.在新建的laravel项目中建立如下目录 packages/yuansir/toastr/src ,packages 目录和 app 目录同级。我们开发包的代码都放在这个src目录中,yuansir和toastr完全自定义。

2.修改项目的composer.json,设定PSR-4命名空间:

"autoload": { "classmap": [ "database" ], "psr-4": { "App\\": "app/", "Yuansir\\Toastr\\": "packages/yuansir/toastr/src/" }
    },

别忘了执行autoload

composer dump-autoload

3.为我们的包初始化一个composer.json文件,熟悉composer的应该都知道这玩意是干嘛的了

$ cd pacages/yuansir/toastr/src $ composer init

按照提示填写相关信息,有些信息可以不用填写,后面自己在composer.json中添加就可以了,生成的示例如下:

{
    "name": "ryan/toastr-for-laravel",
    "description": "toastr.js for laravel5",
    "authors": [
        {
            "name": "Ryan",
            "email": "[email protected]" }
    ],
    "require": {} }

4.开始开发,新建Service Provider

php artisan make:provider ToastrServiceProvider

将生成的app/Providers/ToastrServiceProvider.php文件移动到我们的packages/yuansir/toastr/src目录下面,并注册ToastrServiceProviderconfig/app.php 的providers 中。

'providers' => [ /*
         * Laravel Framework Service Providers...
         */ ...... /*
         * Application Service Providers...
         */ ......
        Yuansir\Toastr\ToastrServiceProvider::class,
    ],

5.新建packages/yuansir/toastr/src/config/toastr.php 来保存toastr.js的options,options配置还蛮多的,具体可以看它的demo。

<?php return [ 'options' => []
];

关于这个配置在我们包中如何调用的,我们过会来说.

6.新建Toastr类,来实现toastr 的info,success,error,warning的相关实现,代码还是很简单的,packages/yuansir/toastr/src/Toastr.php:

<?php namespace Yuansir\Toastr; use Illuminate\Session\SessionManager; use Illuminate\Config\Repository; class Toastr { /**
     * @var SessionManager
     */ protected $session; /**
     * @var Repository
     */ protected $config; /**
     * @var array
     */ protected $notifications = []; /**
     * Toastr constructor.
     * @param SessionManager $session
     * @param Repository $config
     */ public function __construct(SessionManager $session, Repository $config) { $this->session = $session; $this->config = $config;
    } public function render() { $notifications = $this->session->get('toastr:notifications'); if(!$notifications) { return '';
        } foreach ($notifications as $notification) { $config = $this->config->get('toastr.options'); $javascript = ''; $options = []; if($config) { $options = array_merge($config, $notification['options']);
            } if($options) { $javascript = 'toastr.options = ' . json_encode($options) . ';';
            } $message = str_replace("'", "\\'", $notification['message']); $title = $notification['title'] ? str_replace("'", "\\'", $notification['title']) : null; $javascript .= " toastr.{$notification['type']}('$message','$title');";
        } return view('Toastr::toastr', compact('javascript'));
    } /**
     * Add notification
     * @param $type
     * @param $message
     * @param null $title
     * @param array $options
     * @return bool
     */ public function add($type, $message, $title = null, $options = []) { $types = ['info', 'warning', 'success', 'error']; if(!in_array($type, $types)) { return false;
        } $this->notifications[] = [ 'type' => $type, 'title' => $title, 'message' => $message, 'options' => $options ]; $this->session->flash('toastr:notifications', $this->notifications);
    } /**
     * Add info notification
     * @param $message
     * @param null $title
     * @param array $options
     */ public function info($message, $title = null, $options = []) { $this->add('info', $message, $title, $options);
    } /**
     * Add warning notification
     * @param $message
     * @param null $title
     * @param array $options
     */ public function warning($message, $title = null, $options = []) { $this->add('warning', $message, $title, $options);
    } /**
     * Add success notification
     * @param $message
     * @param null $title
     * @param array $options
     */ public function success($message, $title = null, $options = []) { $this->add('success', $message, $title, $options);
    } /**
     * Add error notification
     * @param $message
     * @param null $title
     * @param array $options
     */ public function error($message, $title = null, $options = []) { $this->add('error', $message, $title, $options);
    } /**
     * Clear notifications
     */ public function clear() { $this->notifications = [];
    }
}

7.我们看到view(‘Toastr::toastr’, compact(‘javascript’));,那么就是需要一个视图文件了,关于Toastr::toastr是什么鬼我们过会来说,新建 packages/yuansir/toastr/src/views/toastr.blade.php 视图文件:

<link href="http://cdn.bootcss.com/toastr.js/latest/css/toastr.min.css" rel="stylesheet"> <script src="http://cdn.bootcss.com/toastr.js/latest/js/toastr.min.js"></script> <script type="text/javascript">{!! $javascript !!}</script>

就是引入了tastr插件,输出我们render方法中的$javascript

8.建立Facade,新建packages/yuansir/toastr/src/Facades/Toastr.php

<?php namespace Yuansir\Toastr\Facades; use Illuminate\Support\Facades\Facade; class Toastr extends Facade { protected static function getFacadeAccessor() { return 'toastr';
    }
}

9.修改ToastrServiceProvider:

<?php namespace Yuansir\Toastr; use Illuminate\Support\ServiceProvider; class ToastrServiceProvider extends ServiceProvider { /**
     * Bootstrap the application services.
     *
     * @return void
     */ public function boot() { $this->loadViewsFrom(__DIR__ . '/views', 'Toastr'); $this->publishes([ __DIR__.'/views' => base_path('resources/views/vendor/toastr'), __DIR__.'/config/toastr.php' => config_path('toastr.php'),
        ]);
    } /**
     * Register the application services.
     *
     * @return void
     */ public function register() { $this->app['toastr'] = $this->app->share(function ($app) { return new Toastr($app['session'], $app['config']);
        });
    } /**
     * Get the services provided by the provider.
     *
     * @return array
     */ public function provides() { return ['toastr'];
    }
}

$this->loadViewsFrom(__DIR__ . ‘/views’, ‘Toastr’); 就是表示Toastr命名空间的视图文件冲当前目录的views目录中渲染,所以我们上面用 return view(‘Toastr::toastr’, compact(‘javascript’));

$this->publishes 在执行php artisan vendor:publish 时会将对应的目录和文件复制到对应的位置

10.测试下是否可行,修改 config/app.php 添加如下:

/*
    |--------------------------------------------------------------------------
    | Class Aliases
    |--------------------------------------------------------------------------
    |
    | This array of class aliases will be registered when this application
    | is started. However, feel free to register as many as you wish as
    | the aliases are "lazy" loaded so they don't hinder performance.
    |
    */ 'aliases' => [
        ...... 'Toastr' => Yuansir\Toastr\Facades\Toastr::class,

    ],

写个控制器放进去试试:

<?php namespace App\Http\Controllers; use App\Http\Requests; use Illuminate\Http\Request; use Toastr; class HomeController extends Controller { /**
     * Create a new controller instance.
     *
     * @return void
     */ public function __construct() { //略 } /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */ public function index(Request $request) {
        Toastr::error('你好啊','标题'); return view('home');
    }
}

反正我测试是OK了,就不截图了!!

11.修改命名空间到包的composer.json,因为别人安装这个包的时候不可能也去改项目composer.json的PSR-4的autoload,所以我们把PSR-4的命名空间加到这个包的composer.json中去,修改packages/yuansir/toastr/src/composer.json 如下:

{ "name": "ryan/toastr-for-laravel", "description": "toastr.js for laravel5", "authors": [
        { "name": "Ryan", "email": "[email protected]" }
    ], "require": {}, "autoload": { "psr-4": { "Yuansir\\Toastr\\": "src/" }
    }
}

12.建立Github项目

](http://website-static.qiniudn.com/wp-content/uploads/2016/01/EE32D501-A968-4D6C-9F77-0661137F7360.png)

将代码push到项目中去:

$ cd packages/yuansir/toastr/ $ git init $ git add . $ git commit -m "add package source files." $ git remote add origin git@github.com:yuansir/toastr-for-laravel5.git $ git push -u origin master $ git tag -a 1.0.0 -m "version 1.0.0" $ git push --tags

13.提交到Packagist,打开到packagist.org,登陆后点击右边上角的 submit,并填入git的项目地址[email protected]:yuansir/toastr-for-laravel5.git 点击check 就OK了

](http://website-static.qiniudn.com/wp-content/uploads/2016/01/D9AB1D5A-C1BC-4A01-8A78-D1EDB859822E.png)

Laravel Composer Package 开发实战 toastr-for-laravel5_第1张图片](http://website-static.qiniudn.com/wp-content/uploads/2016/01/705850F3-B2AA-453F-B0DB-6196BE9C0CB0.png)

到此结束,大功告成,这样一个Laravel 的 composer 包就开发完成了。

到此结束,大功告成,这样一个Laravel 的 composer 包就开发完成了。
这个教程的源码和这个包的安装使用方法详见github https://github.com/yuansir/toastr-for-laravel5

到此结束,大功告成,这样一个Laravel 的 composer 包就开发完成了。
这个教程的源码和这个包的安装使用方法详见github https://github.com/yuansir/toastr-for-laravel5
如有问题欢迎指正!

你可能感兴趣的:(PHP,laravel)