Widget.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /**
  3. * User: Mike
  4. * Email: m@9026.com
  5. * Date: 2016/6/30
  6. * Time: 14:37
  7. */
  8. namespace App\Widget;
  9. use Closure;
  10. use Illuminate\Container\Container;
  11. use Illuminate\Support\Str;
  12. use Illuminate\View\Compilers\BladeCompiler;
  13. class Widget
  14. {
  15. protected $container;
  16. protected $blade;
  17. protected $groups = array();
  18. protected $widgets = array();
  19. public function __construct( Container $container, BladeCompiler $blade )
  20. {
  21. $this->container = $container;
  22. $this->blade = $blade;
  23. }
  24. public function register( $name, $callback )
  25. {
  26. $this->widgets[ $name ] = $callback;
  27. $this->registerTag( $name );
  28. }
  29. protected function registerTag( $method )
  30. {
  31. $this->blade->directive( $method, function ( $expression ) use ( $method ) {
  32. return '<?php echo \Widget::' . $method . $expression . '; ?>';
  33. } );
  34. }
  35. public function exists( $name )
  36. {
  37. return array_key_exists( $name, $this->widgets );
  38. }
  39. public function call( $name, array $parameters = array() )
  40. {
  41. if ( $this->groupExists( $name ) ) return $this->callGroup( $name, $parameters );
  42. if ( $this->exists( $name ) ) {
  43. $callback = $this->widgets[ $name ];
  44. return $this->getCallback( $callback, $parameters );
  45. }
  46. return null;
  47. }
  48. public function attribute( $name, $attr )
  49. {
  50. if ( $this->exists( $name ) ) {
  51. $name = $this->widgets[ $name ];
  52. $class = new \ReflectionClass( $name );
  53. if ( $class->hasProperty( $attr ) ) {
  54. $properties = $class->getDefaultProperties();
  55. return $properties[ $attr ];
  56. }
  57. }
  58. return null;
  59. }
  60. public function method( $name, $dataSource )
  61. {
  62. if ( $this->exists( $name ) ) {
  63. $name = $this->widgets[ $name ];
  64. $class = new \ReflectionClass( $name );
  65. $instance = $class->newInstanceArgs();
  66. return $instance->$dataSource();
  67. }
  68. return null;
  69. }
  70. public function view( $name, $dataSourceView )
  71. {
  72. $name = ucfirst( $name );
  73. if ( $this->exists( $name ) ) {
  74. $dataSourceView = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . $dataSourceView;
  75. /*// let's add /app/custom_views via namespace
  76. view()->addNamespace( 'my_views', app_path( 'custom_views' ) );
  77. view( 'my_views::some.view.name' ); // /app/custom_views/some/view/name.blade.php
  78. // 或者
  79. view()->addLocation( app_path( 'cutom_views' ) );
  80. view( 'some.view.name' ); // search in /app/views first, then custom locations*/
  81. view()->addNamespace( $name, dirname( $dataSourceView ) );
  82. return View( $name . '::' . basename( $dataSourceView ) );
  83. }
  84. }
  85. protected function getCallback( $callback, array $parameters )
  86. {
  87. if ( $callback instanceof Closure ) {
  88. return $this->createCallableCallback( $callback, $parameters );
  89. } elseif ( is_string( $callback ) ) {
  90. return $this->createStringCallback( $callback, $parameters );
  91. } else {
  92. return null;
  93. }
  94. }
  95. protected function createStringCallback( $callback, array $parameters )
  96. {
  97. if ( function_exists( $callback ) ) {
  98. return $this->createCallableCallback( $callback, $parameters );
  99. } else {
  100. return $this->createClassCallback( $callback, $parameters );
  101. }
  102. }
  103. protected function createCallableCallback( $callback, array $parameters )
  104. {
  105. return call_user_func_array( $callback, $parameters );
  106. }
  107. protected function createClassCallback( $callback, array $parameters )
  108. {
  109. list( $className, $method ) = Str::parseCallback( $callback, 'run' );
  110. $instance = $this->container->make( $className );
  111. $callable = array( $instance, $method );
  112. return $this->createCallableCallback( $callable, $parameters );
  113. }
  114. public function group( $name, array $widgets )
  115. {
  116. $this->groups[ $name ] = $widgets;
  117. $this->registerTag( $name );
  118. }
  119. public function groupExists( $name )
  120. {
  121. return array_key_exists( $name, $this->groups );
  122. }
  123. public function callGroup( $name, $parameters = array() )
  124. {
  125. if ( !$this->groupExists( $name ) ) return null;
  126. $result = '';
  127. foreach ( $this->groups[ $name ] as $key => $plugin ) {
  128. $result .= $this->call( $plugin, array_get( $parameters, $key, array() ) );
  129. }
  130. return $result;
  131. }
  132. public function __call( $method, $parameters = array() )
  133. {
  134. return $this->call( $method, $parameters );
  135. }
  136. }