1<?php 2/** 3 * This file is part of the Tmdb PHP API created by Michael Roterman. 4 * 5 * For the full copyright and license information, please view the LICENSE 6 * file that was distributed with this source code. 7 * 8 * @package Tmdb 9 * @author Michael Roterman <michael@wtfz.net> 10 * @copyright (c) 2013, Michael Roterman 11 * @version 0.0.1 12 */ 13namespace Tmdb\Factory; 14 15use Tmdb\Event\HydrationEvent; 16use Tmdb\Event\TmdbEvents; 17use Tmdb\HttpClient\HttpClient; 18use Tmdb\Model\AbstractModel; 19use Tmdb\Model\Collection\ResultCollection; 20use Tmdb\Model\Common\AccountStates; 21use Tmdb\Model\Common\GenericCollection; 22use Tmdb\Model\Common\Rating; 23use Tmdb\Model\Lists\Result; 24 25/** 26 * Class AbstractFactory 27 * @package Tmdb\Factory 28 */ 29abstract class AbstractFactory 30{ 31 /** 32 * @var HttpClient 33 */ 34 protected $httpClient; 35 36 /** 37 * Constructor 38 * 39 * @param HttpClient $httpClient 40 */ 41 public function __construct(HttpClient $httpClient) 42 { 43 $this->httpClient = $httpClient; 44 } 45 46 /** 47 * Convert an array to an hydrated object 48 * 49 * @param array $data 50 * @return AbstractModel 51 */ 52 abstract public function create(array $data = []); 53 54 /** 55 * Convert an array with an collection of items to an hydrated object collection 56 * 57 * @param array $data 58 * @return GenericCollection 59 */ 60 abstract public function createCollection(array $data = []); 61 62 /** 63 * Get the http client 64 * 65 * @return HttpClient 66 */ 67 protected function getHttpClient() 68 { 69 return $this->httpClient; 70 } 71 72 /** 73 * Create a generic collection of data and map it on the class by it's static parameter $properties 74 * 75 * @param array $data 76 * @param $class 77 * @return GenericCollection 78 */ 79 protected function createGenericCollection($data = [], $class) 80 { 81 if (is_object($class)) { 82 $class = get_class($class); 83 } 84 85 $collection = new GenericCollection(); 86 87 if (null === $data) { 88 return $collection; 89 } 90 91 foreach ($data as $item) { 92 $collection->add(null, $this->hydrate(new $class(), $item)); 93 } 94 95 return $collection; 96 } 97 98 /** 99 * Create a result collection 100 * 101 * @param array $data 102 * @param string $method 103 * @return ResultCollection 104 */ 105 public function createResultCollection($data = [], $method = 'create') 106 { 107 $collection = new ResultCollection(); 108 109 if (null === $data) { 110 return $collection; 111 } 112 113 if (array_key_exists('page', $data)) { 114 $collection->setPage($data['page']); 115 } 116 117 if (array_key_exists('total_pages', $data)) { 118 $collection->setTotalPages($data['total_pages']); 119 } 120 121 if (array_key_exists('total_results', $data)) { 122 $collection->setTotalResults($data['total_results']); 123 } 124 125 if (array_key_exists('results', $data)) { 126 $data = $data['results']; 127 } 128 129 foreach ($data as $item) { 130 $collection->add(null, $this->$method($item)); 131 } 132 133 return $collection; 134 } 135 136 /** 137 * Create a generic collection of data and map it on the class by it's static parameter $properties 138 * 139 * @param array $data 140 * @param AbstractModel $class 141 * @param GenericCollection $collection 142 * @return GenericCollection 143 */ 144 protected function createCustomCollection($data = [], $class, $collection) 145 { 146 if (is_object($class)) { 147 $class = get_class($class); 148 } 149 150 if (null === $data) { 151 return $collection; 152 } 153 154 foreach ($data as $item) { 155 $collection->add(null, $this->hydrate(new $class(), $item)); 156 } 157 158 return $collection; 159 } 160 161 /** 162 * Create an generic collection of an array that consists out of a mix of movies and tv shows 163 * 164 * @param array $data 165 * @return GenericCollection 166 */ 167 protected function createGenericCollectionFromMediaTypes($data = []) 168 { 169 $movieFactory = new MovieFactory($this->getHttpClient()); 170 $tvFactory = new TvFactory($this->getHttpClient()); 171 $collection = new GenericCollection(); 172 173 foreach ($data as $item) { 174 switch ($item['media_type']) { 175 case "movie": 176 $collection->add(null, $movieFactory->create($item)); 177 break; 178 179 case "tv": 180 $collection->add(null, $tvFactory->create($item)); 181 break; 182 183 default: 184 throw new \RuntimeException('Unknown media type "%s"', $item['media_type']); 185 } 186 } 187 188 return $collection; 189 } 190 191 /** 192 * Create rating 193 * 194 * @param array $data 195 * @return \Tmdb\Model\AbstractModel 196 */ 197 public function createRating(array $data = []) 198 { 199 return $this->hydrate(new Rating(), $data); 200 } 201 202 /** 203 * Create the account states 204 * 205 * @param array $data 206 * @return \Tmdb\Model\AbstractModel 207 */ 208 public function createAccountStates(array $data = []) 209 { 210 $accountStates = new AccountStates(); 211 212 if (array_key_exists('rated', $data)) { 213 if ($data['rated']) { 214 $rating = new Rating(); 215 216 $accountStates->setRated($this->hydrate($rating, $data['rated'])); 217 } else { 218 $accountStates->setRated(false); 219 } 220 } 221 222 return $this->hydrate($accountStates, $data); 223 } 224 225 /** 226 * Create result 227 * 228 * @param array $data 229 * @return \Tmdb\Model\AbstractModel 230 */ 231 public function createResult(array $data = []) 232 { 233 return $this->hydrate(new Result(), $data); 234 } 235 236 /** 237 * Hydrate the object with data 238 * 239 * @param AbstractModel $subject 240 * @param array $data 241 * @return AbstractModel 242 */ 243 protected function hydrate(AbstractModel $subject, $data = []) 244 { 245 $httpClient = $this->getHttpClient(); 246 247 $event = new HydrationEvent($subject, $data); 248 $event->setLastRequest($httpClient->getLastRequest()); 249 $event->setLastResponse($httpClient->getLastResponse()); 250 251 $this->getHttpClient()->getEventDispatcher()->dispatch(TmdbEvents::HYDRATE, $event); 252 253 return $event->getSubject(); 254 } 255} 256