1: <?php
2: /**
3: * This file is part of the Pipeliner API client library for PHP
4: *
5: * Copyright 2014 Pipelinersales, Inc. All Rights Reserved.
6: * For the full license information, see the attached LICENSE file.
7: */
8:
9: namespace PipelinerSales\ApiClient;
10:
11: use PipelinerSales\ApiClient\Http\CurlHttpClient;
12: use PipelinerSales\ApiClient\Http\PipelinerHttpException;
13: use PipelinerSales\ApiClient\Repository\RepositoryInterface;
14: use PipelinerSales\ApiClient\Repository\RepositoryFactoryInterface;
15: use PipelinerSales\ApiClient\Repository\Rest\RestRepositoryFactory;
16: use PipelinerSales\ApiClient\Repository\Rest\RestInfoMethods;
17:
18: /**
19: * The client context
20: *
21: * @property-read RepositoryInterface $accounts
22: * @property-read RepositoryInterface $accountTypes
23: * @property-read RepositoryInterface $activities
24: * @property-read RepositoryInterface $activityTypes
25: * @property-read RepositoryInterface $addressbookRelations (pipeline version 14+)
26: * @property-read RepositoryInterface $appointments
27: * @property-read RepositoryInterface $clients
28: * @property-read RepositoryInterface $competencies (pipeline version 11-14)
29: * @property-read RepositoryInterface $contacts
30: * @property-read RepositoryInterface $currencies
31: * @property-read RepositoryInterface $data
32: * @property-read RepositoryInterface $documents
33: * @property-read RepositoryInterface $emails (pipeline version 12+)
34: * @property-read RepositoryInterface $exRateLists
35: * @property-read RepositoryInterface $industries
36: * @property-read RepositoryInterface $integrationEnvs
37: * @property-read RepositoryInterface $leads
38: * @property-read RepositoryInterface $masterRights
39: * @property-read RepositoryInterface $messages
40: * @property-read RepositoryInterface $notes
41: * @property-read RepositoryInterface $opportunities
42: * @property-read RepositoryInterface $opptyAccountRelations (pipeline version 14+)
43: * @property-read RepositoryInterface $opptyContactRelations (pipeline version 14+)
44: * @property-read RepositoryInterface $opptyContactRoles (pipeline version 15+)
45: * @property-read RepositoryInterface $opptyProductRelations (pipeline version 14+)
46: * @property-read RepositoryInterface $products
47: * @property-read RepositoryInterface $productCategories (pipeline version 14+)
48: * @property-read RepositoryInterface $productPriceLists (pipeline version 14+)
49: * @property-read RepositoryInterface $productPriceListPrices (pipeline version 14+)
50: * @property-read RepositoryInterface $reasonOfCloses
51: * @property-read RepositoryInterface $relevancies (pipeline version 11-14)
52: * @property-read RepositoryInterface $reminders
53: * @property-read RepositoryInterface $salesRoles (pipeline version 15+)
54: * @property-read RepositoryInterface $salesUnits
55: * @property-read RepositoryInterface $stages
56: */
57: class PipelinerClient
58: {
59:
60: private $entitiesToCollections;
61: private $collectionsToEntities;
62: private $repositories = array();
63: private $repositoryFactory;
64: private $infoMethods;
65: private $pipelineVersion;
66:
67: /**
68: * Constructor. To create a client object configured for most typical uses, use the static {@see create} method.
69: *
70: * @param array $entityTypes an associative array with entity names as keys and their plurals as values
71: * @param RepositoryFactoryInterface $repositoryFactory
72: * @param InfoMethodsInterface $infoMethods
73: */
74: public function __construct(
75: array $entityTypes,
76: RepositoryFactoryInterface $repositoryFactory,
77: InfoMethodsInterface $infoMethods
78: ) {
79: $this->setEntityTypes($entityTypes);
80: $this->repositoryFactory = $repositoryFactory;
81: $this->infoMethods = $infoMethods;
82: $this->pipelineVersion = null;
83: }
84:
85: /**
86: * Creates a PipelinerClient object with sensible default configuration.
87: * Will perform a HTTP request to fetch the existing entity types for the pipeline.
88: *
89: * @param string $url base url of the REST server, without the trailing slash
90: * @param string $pipelineId the unique team pipeline id
91: * @param string $apiToken API token
92: * @param string $password API password
93: * @return PipelinerClient
94: * @throws PipelinerClientException when trying to use an unsupported pipeline version
95: * @throws PipelinerHttpException if fetching the pipeline version fails
96: */
97: public static function create($url, $pipelineId, $apiToken, $password)
98: {
99: $baseUrl = $url . '/rest_services/v1/' . $pipelineId;
100:
101: $httpClient = new CurlHttpClient();
102: $httpClient->setUserCredentials($apiToken, $password);
103:
104: $dateTimeFormat = Defaults::DATE_FORMAT;
105: $repoFactory = new RestRepositoryFactory($baseUrl, $httpClient, $dateTimeFormat);
106:
107: $infoMethods = new RestInfoMethods($baseUrl, $httpClient);
108: $entityTypes = array_flip($infoMethods->fetchEntityPublic());
109:
110: $client = new PipelinerClient($entityTypes, $repoFactory, $infoMethods);
111: return $client;
112: }
113:
114: /**
115: * Returns an associative array of recognized entity names to the plurals of their names
116: * @return array
117: */
118: public function getEntityTypes()
119: {
120: return $this->entitiesToCollections;
121: }
122:
123: /**
124: * Returns an object for retrieving various information from the server.
125: * @return InfoMethodsInterface
126: */
127: public function getServerInfo()
128: {
129: return $this->infoMethods;
130: }
131:
132: /**
133: * Magic getter for repositories. Calls {@see getRepository} for
134: * known entity types.
135: *
136: * @param string $name camelCase name of the collection (e.g. activityTypes)
137: * @return RepositoryInterface
138: */
139: public function __get($name)
140: {
141: $entityName = $this->collectionsToEntities[ucfirst($name)];
142: return $this->getRepository($entityName);
143: }
144:
145: /**
146: * Returns a repository for the specified entity.
147: *
148: * @param mixed $entityName an {@see Entity} object or entity name,
149: * can be both singular (Account) and plural (Accounts)
150: * @return RepositoryInterface
151: */
152: public function getRepository($entityName)
153: {
154: if ($entityName instanceof Entity) {
155: $entityName = $entityName->getType();
156: }
157:
158: if (!isset($this->repositories[$entityName])) {
159: $plural = $this->getCollectionName($entityName);
160: $this->repositories[$entityName] = $this->repositoryFactory->createRepository(
161: $entityName,
162: $plural
163: );
164: }
165:
166: return $this->repositories[$entityName];
167: }
168:
169: private function setEntityTypes($entitiesToCollections)
170: {
171: $this->entitiesToCollections = $entitiesToCollections;
172: $this->collectionsToEntities = array_flip($this->entitiesToCollections);
173: }
174:
175: private function getCollectionName($entityName)
176: {
177: return $this->entitiesToCollections[$entityName];
178: }
179:
180: public function getPipelineVersion()
181: {
182: if ($this->pipelineVersion === null) {
183: $this->pipelineVersion = $this->infoMethods->fetchTeamPipelineVersion();
184: }
185: return $this->pipelineVersion;
186: }
187:
188: public function registeryEntityType($entityName, $collectionName)
189: {
190: $this->entitiesToCollections[$entityName] = $collectionName;
191: }
192: }
193: