├── tests └── .gitkeep ├── .gitignore ├── .travis.yml ├── src ├── Exceptions.php ├── Facades │ └── HMVC.php ├── Commands │ └── HmvcCallCommand.php ├── HmvcServiceProvider.php └── Hmvc.php ├── phpunit.xml ├── composer.json └── README.md /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | - 5.6 8 | - hhvm 9 | 10 | before_script: 11 | - composer self-update 12 | - composer install --prefer-source --no-interaction --dev 13 | 14 | script: phpunit 15 | -------------------------------------------------------------------------------- /src/Exceptions.php: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "teepluss/hmvc", 3 | "description": "Laravel HMVC.", 4 | "keywords": ["laravel", "hmvc"], 5 | "homepage": "https://github.com/teepluss/laravel-hmvc", 6 | "type": "library", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Teepluss", 11 | "email": "teepluss@gmail.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.4.0", 16 | "guzzle/guzzle": "3.9.1" 17 | }, 18 | "require-dev": { 19 | "illuminate/support": ">=5.0.1" 20 | }, 21 | "autoload": { 22 | "classmap": [ 23 | "src/Exceptions.php" 24 | ], 25 | "psr-4": { 26 | "Teepluss\\Hmvc\\": "src/" 27 | } 28 | }, 29 | "minimum-stability": "dev" 30 | } 31 | -------------------------------------------------------------------------------- /src/Commands/HmvcCallCommand.php: -------------------------------------------------------------------------------- 1 | hmvc = $hmvc; 42 | } 43 | 44 | /** 45 | * Execute the console command. 46 | * 47 | * @return mixed 48 | */ 49 | public function fire() 50 | { 51 | //var_dump(get_class_methods($this->hmvc)); 52 | echo $this->hmvc->get('/'); 53 | } 54 | 55 | /** 56 | * Get the console command arguments. 57 | * 58 | * @return array 59 | */ 60 | protected function getArguments() 61 | { 62 | return [ 63 | ['example', InputArgument::OPTIONAL, 'An example argument.'], 64 | ]; 65 | } 66 | 67 | /** 68 | * Get the console command options. 69 | * 70 | * @return array 71 | */ 72 | protected function getOptions() 73 | { 74 | return [ 75 | ['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null], 76 | ]; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/HmvcServiceProvider.php: -------------------------------------------------------------------------------- 1 | alias('HMVC', 'Teepluss\Hmvc\Facades\HMVC'); 25 | } 26 | 27 | /** 28 | * Register the service provider. 29 | * 30 | * @return void 31 | */ 32 | public function register() 33 | { 34 | // Register providers. 35 | $this->registerHmvc(); 36 | 37 | // Register commands. 38 | //$this->registerHmvcCall(); 39 | 40 | // Add to commands. 41 | //$this->commands('hmvc.call'); 42 | } 43 | 44 | /** 45 | * Register Api. 46 | * 47 | * @return void 48 | */ 49 | protected function registerHmvc() 50 | { 51 | $this->app['hmvc'] = $this->app->share(function($app) 52 | { 53 | $config = []; 54 | 55 | $remoteClient = new Client(); 56 | 57 | return new Hmvc($config, $app['router'], $app['request'], $remoteClient); 58 | }); 59 | } 60 | 61 | // protected function registerHmvcCall() 62 | // { 63 | // $this->app['hmvc.call'] = $this->app->share(function($app) 64 | // { 65 | // return new Commands\HmvcCallCommand($app['hmvc']); 66 | // }); 67 | // } 68 | 69 | /** 70 | * Get the services provided by the provider. 71 | * 72 | * @return array 73 | */ 74 | public function provides() 75 | { 76 | return array('hmvc'); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Laravel HMVC. 2 | 3 | ### For Laravel 4, please use the [v1.x branch](https://github.com/teepluss/laravel-hmvc/tree/v1.x)! 4 | 5 | HMVC is a tool for making internal request. 6 | 7 | ### Installation 8 | 9 | - [HMVC on Packagist](https://packagist.org/packages/teepluss/hmvc) 10 | - [HMVC on GitHub](https://github.com/teepluss/laravel-hmvc) 11 | 12 | To get the lastest version of HMVC simply require it in your `composer.json` file. 13 | 14 | ~~~ 15 | "teepluss/hmvc": "dev-master" 16 | ~~~ 17 | 18 | You'll then need to run `composer install` to download it and have the autoloader updated. 19 | 20 | Once HMVC is installed you need to register the service provider with the application. Open up `config/app.php` and find the `providers` key. 21 | 22 | ~~~ 23 | 'providers' => array( 24 | 25 | 'Teepluss\Hmvc\HmvcServiceProvider' 26 | 27 | ) 28 | ~~~ 29 | 30 | HMVC also ships with a facade which provides the static syntax for creating collections. You can register the facade in the `aliases` key of your `config/app.php` file. 31 | 32 | ~~~ 33 | 'aliases' => [ 34 | 35 | 'HMVC' => 'Teepluss\Hmvc\Facades\HMVC', 36 | 37 | ] 38 | ~~~ 39 | 40 | ## Usage 41 | 42 | HMVC helping you to work with internal request. 43 | 44 | - [Internal testing request](#internal-testing-request) 45 | - [Calling via artisan CLI](#calling-via-artisan-cli) 46 | 47 | ### Internal testing request. 48 | 49 | ~~~php 50 | // GET Request. 51 | HMVC::get('user/1'); 52 | 53 | // POST Request. 54 | HMVC::post('user', array('title' => 'Demo')); 55 | 56 | // PATCH Request. 57 | HMVC::patch('user/1', array('title' => 'Changed')); 58 | 59 | // PUT Request. 60 | HMVC::put('user/1', array('title' => 'Changed')); 61 | 62 | // DELETE Request. 63 | HMVC::delete('user/1'); 64 | 65 | // Internal request with domain route. 66 | HMVC::invoke('/someinternalpath', 'post', array('param' => 1)) 67 | 68 | // You can make remote request without changing code also. 69 | HMVC::post('http://api.github.com', array('username' => 'teepluss')); 70 | 71 | // Request remote with invokeRemote. 72 | HMVC::invokeRemote('http://api.github.com', 'post', array('username' => 'teepluss')); 73 | 74 | // Configure remote client. 75 | $config = array('auth' => array('admin', 'admin')); 76 | echo HMVC::configureRemoteClient($config)->get('http://127.0.0.1:9200'); 77 | 78 | // Get Guzzle to use other features. 79 | $guzzle = HMVC::getRemoteClient(); 80 | ~~~ 81 | >> Remote request using [Guzzle](http://guzzlephp.org/) as an adapter. 82 | 83 | ## Support or Contact 84 | 85 | If you have some problem, Contact teepluss@gmail.com 86 | 87 | [![Support via PayPal](https://rawgithub.com/chris---/Donation-Badges/master/paypal.jpeg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9GEC8J7FAG6JA) -------------------------------------------------------------------------------- /src/Hmvc.php: -------------------------------------------------------------------------------- 1 | config = $config; 53 | 54 | $this->router = $router; 55 | 56 | $this->request = $request; 57 | 58 | $this->remoteClient = $remoteClient; 59 | } 60 | 61 | /** 62 | * Remote client for http request. 63 | * 64 | * @return Client 65 | */ 66 | public function getRemoteClient() 67 | { 68 | return $this->remoteClient; 69 | } 70 | 71 | /** 72 | * Call internal URI with parameters. 73 | * 74 | * @param string $uri 75 | * @param string $method 76 | * @param array $parameters 77 | * @return mixed 78 | */ 79 | public function invoke($uri, $method, $parameters = array()) 80 | { 81 | // Request URI. 82 | $uri = '/'.ltrim($uri, '/'); 83 | 84 | try 85 | { 86 | // Store the original request data and route. 87 | $originalInput = $this->request->input(); 88 | $originalRoute = $this->router->getCurrentRoute(); 89 | 90 | // Masking route to allow testing with PHPUnit. 91 | // if ( ! $originalRoute instanceof Route) 92 | // { 93 | // $originalRoute = new Route(new \Symfony\Component\HttpFoundation\Request()); 94 | // } 95 | 96 | $requestMethod = strtoupper($method); 97 | 98 | // Create a new request to the API resource 99 | $request = $this->request->create($uri, $requestMethod, $parameters); 100 | 101 | // Replace request method and input. 102 | $this->request->setMethod($requestMethod); 103 | $this->request->replace($request->input()); 104 | 105 | // Dispatch request. 106 | $dispatch = $this->router->dispatch($request); 107 | 108 | if (method_exists($dispatch, 'getOriginalContent')) 109 | { 110 | $response = $dispatch->getOriginalContent(); 111 | } 112 | else 113 | { 114 | $response = $dispatch->getContent(); 115 | } 116 | 117 | // Decode json content. 118 | if ($dispatch->headers->get('content-type') == 'application/json') 119 | { 120 | if (function_exists('json_decode') and is_string($response)) 121 | { 122 | $response = json_decode($response, true); 123 | } 124 | } 125 | 126 | // Restore the request input and route back to the original state. 127 | $this->request->replace($originalInput); 128 | 129 | return $response; 130 | } 131 | catch (NotFoundHttpException $e) 132 | { 133 | throw new HmvcNotFoundHttpException('Request Not Found.'); 134 | } 135 | catch (FatalErrorException $e) 136 | { 137 | throw new HmvcFatalErrorException($e->getMessage()); 138 | } 139 | } 140 | 141 | /** 142 | * Configure remote client for http request. 143 | * 144 | * @param array $configuration 145 | * 146 | * array 147 | *( 148 | * 'verify' => false, //allows self signed certificates 149 | * 'verify', '/path/to/cacert.pem', //custom certificate 150 | * 'headers/X-Foo', 'Bar', //custom header 151 | * 'auth', array('username', 'password', 'Digest'), //custom authentication 152 | *) 153 | */ 154 | public function configureRemoteClient($configurations) 155 | { 156 | foreach ($configurations as $option => $value) 157 | { 158 | call_user_func_array(array($this->remoteClient, 'setDefaultOption'), array($option, $value)); 159 | } 160 | 161 | 162 | //sd($this->remoteClient); 163 | 164 | return $this; 165 | } 166 | 167 | /** 168 | * Invoke with remote request. 169 | * 170 | * @param string $uri 171 | * @param string $method 172 | * @param array $parameters 173 | * @return mixed 174 | */ 175 | public function invokeRemote($uri, $method = 'GET', $parameters = array()) 176 | { 177 | $remoteClient = $this->getRemoteClient(); 178 | 179 | // Make request. 180 | $request = call_user_func_array(array($remoteClient, $method), array($uri, null, $parameters)); 181 | 182 | // Ignore all SSL case. 183 | $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYHOST, false); 184 | $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false); 185 | 186 | // Send request. 187 | $response = $request->send(); 188 | 189 | // Body responsed. 190 | $body = (string) $response->getBody(); 191 | 192 | // Decode json content. 193 | if ($response->getContentType() == 'application/json') 194 | { 195 | if (function_exists('json_decode') and is_string($body)) 196 | { 197 | $body = json_decode($body, true); 198 | } 199 | } 200 | 201 | return $body; 202 | } 203 | 204 | /** 205 | * Alias call method. 206 | * 207 | * @return mixed 208 | */ 209 | public function __call($method, $parameters = array()) 210 | { 211 | if (in_array($method, array('get', 'patch', 'post', 'put', 'delete'))) 212 | { 213 | $uri = array_shift($parameters); 214 | 215 | $parameters = current($parameters); 216 | $parameters = is_array($parameters) ? $parameters : array(); 217 | 218 | if (preg_match('/^http(s)?/', $uri)) 219 | { 220 | return $this->invokeRemote($uri, $method, $parameters); 221 | } 222 | 223 | return $this->invoke($uri, $method, $parameters); 224 | } 225 | } 226 | 227 | } 228 | --------------------------------------------------------------------------------