1: <?php
2:
3: namespace Guzzle\Service\Command\Factory;
4:
5: use Guzzle\Service\Command\CommandInterface;
6: use Guzzle\Service\ClientInterface;
7:
8: /**
9: * Composite factory used by a client object to create command objects utilizing multiple factories
10: */
11: class CompositeFactory implements \IteratorAggregate, \Countable, FactoryInterface
12: {
13: /**
14: * @var array Array of command factories
15: */
16: protected $factories;
17:
18: /**
19: * Get the default chain to use with clients
20: *
21: * @param ClientInterface $client Client to base the chain on
22: *
23: * @return self
24: */
25: public static function getDefaultChain(ClientInterface $client)
26: {
27: $factories = array();
28: if ($description = $client->getDescription()) {
29: $factories[] = new ServiceDescriptionFactory($description);
30: }
31: $factories[] = new ConcreteClassFactory($client);
32:
33: return new self($factories);
34: }
35:
36: /**
37: * @param array $factories Array of command factories
38: */
39: public function __construct(array $factories = array())
40: {
41: $this->factories = $factories;
42: }
43:
44: /**
45: * Add a command factory to the chain
46: *
47: * @param FactoryInterface $factory Factory to add
48: * @param string|FactoryInterface $before Insert the new command factory before a command factory class or object
49: * matching a class name.
50: *
51: * @return CompositeFactory
52: */
53: public function add(FactoryInterface $factory, $before = null)
54: {
55: $pos = null;
56:
57: if ($before) {
58: foreach ($this->factories as $i => $f) {
59: if ($before instanceof FactoryInterface) {
60: if ($f === $before) {
61: $pos = $i;
62: break;
63: }
64: } elseif (is_string($before)) {
65: if ($f instanceof $before) {
66: $pos = $i;
67: break;
68: }
69: }
70: }
71: }
72:
73: if ($pos === null) {
74: $this->factories[] = $factory;
75: } else {
76: array_splice($this->factories, $i, 0, array($factory));
77: }
78:
79: return $this;
80: }
81:
82: /**
83: * Check if the chain contains a specific command factory
84: *
85: * @param FactoryInterface|string $factory Factory to check
86: *
87: * @return bool
88: */
89: public function has($factory)
90: {
91: return (bool) $this->find($factory);
92: }
93:
94: /**
95: * Remove a specific command factory from the chain
96: *
97: * @param string|FactoryInterface $factory Factory to remove by name or instance
98: *
99: * @return CompositeFactory
100: */
101: public function remove($factory = null)
102: {
103: if (!($factory instanceof FactoryInterface)) {
104: $factory = $this->find($factory);
105: }
106:
107: $this->factories = array_values(array_filter($this->factories, function($f) use ($factory) {
108: return $f !== $factory;
109: }));
110:
111: return $this;
112: }
113:
114: /**
115: * Get a command factory by class name
116: *
117: * @param string|FactoryInterface $factory Command factory class or instance
118: *
119: * @return null|FactoryInterface
120: */
121: public function find($factory)
122: {
123: foreach ($this->factories as $f) {
124: if ($factory === $f || (is_string($factory) && $f instanceof $factory)) {
125: return $f;
126: }
127: }
128: }
129:
130: /**
131: * Create a command using the associated command factories
132: *
133: * @param string $name Name of the command
134: * @param array $args Command arguments
135: *
136: * @return CommandInterface
137: */
138: public function factory($name, array $args = array())
139: {
140: foreach ($this->factories as $factory) {
141: $command = $factory->factory($name, $args);
142: if ($command) {
143: return $command;
144: }
145: }
146: }
147:
148: /**
149: * {@inheritdoc}
150: */
151: public function count()
152: {
153: return count($this->factories);
154: }
155:
156: /**
157: * {@inheritdoc}
158: */
159: public function getIterator()
160: {
161: return new \ArrayIterator($this->factories);
162: }
163: }
164: