1: <?php namespace Laravel\CLI\Tasks\Bundle; defined('DS') or die('No direct script access.');
2:
3: use Laravel\IoC;
4: use Laravel\File;
5: use Laravel\Cache;
6: use Laravel\Bundle;
7: use Laravel\Request;
8: use Laravel\CLI\Tasks\Task;
9:
10: class Bundler extends Task {
11:
12: /**
13: * The bundle API repository.
14: *
15: * @var Repository
16: */
17: protected $repository;
18:
19: /**
20: * Create a new bundle manager task.
21: *
22: * @param Repository $repository
23: * @return void
24: */
25: public function __construct($repository)
26: {
27: $this->repository = $repository;
28: }
29:
30: /**
31: * Install the given bundles into the application.
32: *
33: * @param array $bundles
34: * @return void
35: */
36: public function install($bundles)
37: {
38: foreach ($this->get($bundles) as $bundle)
39: {
40: if (Bundle::exists($bundle['name']))
41: {
42: echo "Bundle {$bundle['name']} is already installed.";
43:
44: continue;
45: }
46:
47: // Once we have the bundle information, we can resolve an instance
48: // of a provider and install the bundle into the application and
49: // all of its registered dependencies as well.
50: //
51: // Each bundle provider implements the Provider interface and
52: // is responsible for retrieving the bundle source from its
53: // hosting party and installing it into the application.
54: $path = path('bundle').$this->path($bundle);
55:
56: echo "Fetching [{$bundle['name']}]...";
57:
58: $this->download($bundle, $path);
59:
60: echo "done! Bundle installed.".PHP_EOL;
61: }
62: }
63:
64: /**
65: * Uninstall the given bundles from the application.
66: *
67: * @param array $bundles
68: * @return void
69: */
70: public function uninstall($bundles)
71: {
72: if (count($bundles) == 0)
73: {
74: throw new \Exception("Tell me what bundle to uninstall.");
75: }
76:
77: foreach ($bundles as $name)
78: {
79: if ( ! Bundle::exists($name))
80: {
81: echo "Bundle [{$name}] is not installed.";
82: continue;
83: }
84:
85: echo "Uninstalling [{$name}]...".PHP_EOL;
86: $migrator = IoC::resolve('task: migrate');
87: $migrator->reset($name);
88:
89: $publisher = IoC::resolve('bundle.publisher');
90: $publisher->unpublish($name);
91:
92: $location = Bundle::path($name);
93: File::rmdir($location);
94:
95: echo "Bundle [{$name}] has been uninstalled!".PHP_EOL;
96: }
97:
98: echo "Now, you have to remove those bundle from your application/bundles.php".PHP_EOL;
99: }
100:
101: /**
102: * Upgrade the given bundles for the application.
103: *
104: * @param array $bundles
105: * @return void
106: */
107: public function upgrade($bundles)
108: {
109: if (count($bundles) == 0) $bundles = Bundle::names();
110:
111: foreach ($bundles as $name)
112: {
113: if ( ! Bundle::exists($name))
114: {
115: echo "Bundle [{$name}] is not installed!";
116:
117: continue;
118: }
119:
120: // First we want to retrieve the information for the bundle, such as
121: // where it is currently installed. This will allow us to upgrade
122: // the bundle into it's current installation path.
123: $location = Bundle::path($name);
124:
125: // If the bundle exists, we will grab the data about the bundle from
126: // the API so we can make the right bundle provider for the bundle,
127: // since we don't know the provider used to install.
128: $response = $this->retrieve($name);
129:
130: if ($response['status'] == 'not-found')
131: {
132: continue;
133: }
134:
135: // Once we have the bundle information from the API, we'll simply
136: // recursively delete the bundle and then re-download it using
137: // the correct provider assigned to the bundle.
138: File::rmdir($location);
139:
140: $this->download($response['bundle'], $location);
141:
142: echo "Bundle [{$name}] has been upgraded!".PHP_EOL;
143: }
144: }
145:
146: /**
147: * Gather all of the bundles from the bundle repository.
148: *
149: * @param array $bundles
150: * @return array
151: */
152: protected function get($bundles)
153: {
154: $responses = array();
155:
156: foreach ($bundles as $bundle)
157: {
158: // First we'll call the bundle repository to gather the bundle data
159: // array, which contains all of the information needed to install
160: // the bundle into the Laravel application.
161: $response = $this->retrieve($bundle);
162:
163: if ($response['status'] == 'not-found')
164: {
165: throw new \Exception("There is no bundle named [$bundle].");
166: }
167:
168: // If the bundle was retrieved successfully, we will add it to
169: // our array of bundles, as well as merge all of the bundle's
170: // dependencies into the array of responses.
171: $bundle = $response['bundle'];
172:
173: $responses[] = $bundle;
174:
175: // We'll also get the bundle's declared dependencies so they
176: // can be installed along with the bundle, making it easy
177: // to install a group of bundles.
178: $dependencies = $this->get($bundle['dependencies']);
179:
180: $responses = array_merge($responses, $dependencies);
181: }
182:
183: return $responses;
184: }
185:
186: /**
187: * Publish bundle assets to the public directory.
188: *
189: * @param array $bundles
190: * @return void
191: */
192: public function publish($bundles)
193: {
194: if (count($bundles) == 0) $bundles = Bundle::names();
195:
196: array_walk($bundles, array(IoC::resolve('bundle.publisher'), 'publish'));
197: }
198:
199: /**
200: * Delete bundle assets from the public directory.
201: *
202: * @param array $bundles
203: * @return void
204: */
205: public function unpublish($bundles)
206: {
207: if (count($bundles) == 0) $bundles = Bundle::names();
208:
209: array_walk($bundles, array(IoC::resolve('bundle.publisher'), 'unpublish'));
210: }
211:
212: /**
213: * Install a bundle using a provider.
214: *
215: * @param string $bundle
216: * @param string $path
217: * @return void
218: */
219: protected function download($bundle, $path)
220: {
221: $provider = "bundle.provider: {$bundle['provider']}";
222:
223: IoC::resolve($provider)->install($bundle, $path);
224: }
225:
226: /**
227: * Retrieve a bundle from the repository.
228: *
229: * @param string $bundle
230: * @return array
231: */
232: protected function retrieve($bundle)
233: {
234: $response = $this->repository->get($bundle);
235:
236: if ( ! $response)
237: {
238: throw new \Exception("The bundle API is not responding.");
239: }
240:
241: return $response;
242: }
243:
244: /**
245: * Return the path for a given bundle.
246: *
247: * @param array $bundle
248: * @return string
249: */
250: protected function path($bundle)
251: {
252: return array_get($bundle, 'path', $bundle['name']);
253: }
254:
255: }
256: