Overview

Namespaces

  • NGS
    • Client
      • Exception
    • Converter
    • Patterns
  • PHP

Classes

  • ApplicationProxy
  • CrudProxy
  • DomainProxy
  • HttpRequest
  • QueryString
  • ReportingProxy
  • RestHttp
  • StandardProxy
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: namespace NGS\Client;
  3: 
  4: require_once(__DIR__.'/../Utils.php');
  5: require_once(__DIR__.'/../Name.php');
  6: require_once(__DIR__.'/RestHttp.php');
  7: require_once(__DIR__.'/../Converter/PrimitiveConverter.php');
  8: require_once(__DIR__.'/../Patterns/Repository.php');
  9: 
 10: 
 11: use NGS\Converter\PrimitiveConverter;
 12: use NGS\Name;
 13: use NGS\Patterns\AggregateDomainEvent;
 14: use NGS\Patterns\DomainEvent;
 15: use NGS\Patterns\IDomainObject;
 16: use NGS\Patterns\Repository;
 17: use NGS\Patterns\Specification;
 18: 
 19: /**
 20:  * Proxy service to remote REST-like API for basic domain operations
 21:  * such as searching, counting and event sourcing.
 22:  * It is preferred to use domain patterns instead of this proxy service.
 23:  */
 24: class DomainProxy
 25: {
 26:     const DOMAIN_URI = 'Domain.svc';
 27: 
 28:     /**
 29:      * @var RestHttp Instance of RestHttp client
 30:      */
 31:     protected $http;
 32: 
 33:     /**
 34:      * @var DomainProxy Singleton instance
 35:      */
 36:     protected static $instance;
 37: 
 38:     /**
 39:      * Create a new DomainProxy instance
 40:      *
 41:      * @param RestHttp $http RestHttp instance used for http request.
 42:      * Optionally specify an instance, otherwise use a singleton instance
 43:      */
 44:     public function __construct(RestHttp $http = null)
 45:     {
 46:         $this->http = $http !== null ? $http : RestHttp::instance();
 47:     }
 48: 
 49:     /**
 50:      * Gets singleton instance of Domain.svc proxy
 51:      *
 52:      * @return DomainProxy
 53:      */
 54:     public static function instance()
 55:     {
 56:         if(self::$instance === null)
 57:             self::$instance = new DomainProxy();
 58:         return self::$instance;
 59:     }
 60: 
 61:     /**
 62:      * Returns an array of domain objects uniquely represented with their URIs.
 63:      * Only found objects will be returned (array is empty if no objects are found).
 64:      *
 65:      * Example:<br>
 66:      * <code>
 67:      * $proxy = DomainProxy::instance();
 68:      * $proxy->find('Test\\Item', array('uri1', 'uri2'));
 69:      * </code>
 70:      *
 71:      * @param string $class Domain object class name or instance
 72:      * @param array $uris Array of string URIs
 73:      * @return array Array of found objects or empty array if none found
 74:      */
 75:     public function find($class, array $uris)
 76:     {
 77:         $name = Name::full($class);
 78:         $body = array('Name' => $name, 'Uri' => PrimitiveConverter::toStringArray($uris));
 79:         $response =
 80:             $this->http->sendRequest(
 81:                 ApplicationProxy::APPLICATION_URI.'/GetDomainObject',
 82:                 'POST',
 83:                 json_encode($body),
 84:                 array(200));
 85:         return RestHttp::parseResult($response, $class);
 86:     }
 87: 
 88:     /**
 89:      * Returns an array of all domain objects
 90:      * with up to $limit results.
 91:      *
 92:      * Example:<br>
 93:      * <code>
 94:      * $proxy = DomainProxy::instance();
 95:      * $proxy->search('Test\\Item', 10, 20, array('title' => true));
 96:      * </code>
 97:      *
 98:      * @param string $class Domain object class name or instance
 99:      * @param int $limit Limits maximum number of returned results
100:      * @param int $offset Offset results by this number
101:      * @param array $order Array of key=>value pairs: keys are property names,
102:      * values determine sorting direction: true=ascending, false=descending
103:      * @return array Array of found objects or empty array if none found
104:      */
105:     public function search(
106:         $class,
107:         $limit = null,
108:         $offset = null,
109:         array $order = null)
110:     {
111:         $name = Name::full($class);
112:         $lo = QueryString::formatLimitAndOffsetAndOrder($limit, $offset, $order);
113:         $response =
114:             $this->http->sendRequest(
115:                 self::DOMAIN_URI.'/search/'.rawurlencode($name).($lo ? '?'.$lo : ''),
116:                 'GET',
117:                 null,
118:                 array(200));
119:         return RestHttp::parseResult($response, $class);
120:     }
121: 
122:     /**
123:      * Returns a list of domain objects satisfying {@see NGS\Patterns\Specification}
124:      * with up to $limit results.
125:      *
126:      * @param string        $class
127:      * @param Specification $specification Specification instance used for searching
128:      * @param type          $limit
129:      * @param type          $offset
130:      * @param array         $order
131:      * @return array Array of found objects or empty array if none found
132:      */
133:     public function searchWithSpecification(
134:         $class,
135:         Specification $specification,
136:         $limit = null,
137:         $offset = null,
138:         array $order = null)
139:     {
140:         $objectName = Name::full($class);
141:         $specName = Name::parent($specification).'+'.Name::base($specification);
142:         $lo = QueryString::formatLimitAndOffsetAndOrder($limit, $offset, $order);
143:         $response =
144:             $this->http->sendRequest(
145:                 self::DOMAIN_URI.'/search/'
146:                     .rawurlencode($objectName)
147:                     .'?specification='.rawurlencode($specName)
148:                     .($lo ? '&'.$lo : ''),
149:                 'PUT',
150:                 $specification->toJson(),
151:                 array(200));
152:         return RestHttp::parseResult($response, Name::toClass($class));
153:     }
154: 
155:     /**
156:      * Returns a list of domain objects satisfying conditions in {@see NGS\Patterns\GenericSearch}
157:      *
158:      * @param string|IDomainObject $class
159:      * @param array $filters
160:      * @param type $limit
161:      * @param type $offset
162:      * @param array $order
163:      * @return type
164:      */
165:     public function searchGeneric(
166:         $class,
167:         array $filters = null,
168:         $limit = null,
169:         $offset = null,
170:         array $order = null)
171:     {
172:         $object = Name::full($class);
173:         $lo = QueryString::formatLimitAndOffsetAndOrder($limit, $offset, $order);
174:         $response =
175:             $this->http->sendRequest(
176:                 self::DOMAIN_URI.'/search-generic/'.rawurlencode($object).($lo ? '?'.$lo : ''),
177:                 'PUT',
178:                 json_encode($filters),
179:                 array(200));
180:         return RestHttp::parseResult($response, Name::toClass($object));
181:     }
182: 
183:     /**
184:      * Count total number of domain objects satisfying conditions in {@see NGS\Patterns\GenericSearch}
185:      *
186:      * @param type $class
187:      * @param array $filters
188:      * @return type
189:      */
190:     public function countGeneric(
191:         $class,
192:         array $filters = null)
193:     {
194:         $object = Name::full($class);
195:         $response =
196:             $this->http->sendRequest(
197:                 self::DOMAIN_URI.'/count-generic/'.rawurlencode($object),
198:                 'PUT',
199:                 json_encode($filters),
200:                 array(200));
201:         return RestHttp::parseResult($response, Name::toClass($object));
202:     }
203: 
204:     /**
205:      * Returns a total number of domain objects.
206:      *
207:      * @param string $class
208:      * @return integer Total number of objects
209:      */
210:     public function count($class)
211:     {
212:         $name = Name::full($class);
213:         $response = $this->http->sendRequest(
214:             self::DOMAIN_URI.'/count/'.rawurlencode($name),
215:             'GET',
216:             null,
217:             array(200));
218:         $count = RestHttp::parseResult($response);
219:         return PrimitiveConverter::toInteger($count);
220:     }
221: 
222:     /**
223:      * Count number of domain objects satisfying {@see NGS\Patterns\Specification}
224:      *
225:      * @param Specification $specification
226:      * @return int Total number of objects
227:      */
228:     public function countWithSpecification(Specification $specification)
229:     {
230:         $object = Name::parent($specification);
231:         $name = Name::base($specification);
232:         $response =
233:             $this->http->sendRequest(
234:                 self::DOMAIN_URI.'/count/'.rawurlencode($object).'?specification='.rawurlencode($name),
235:                 'PUT',
236:                 $specification->toJson(),
237:                 array(200));
238:         $count = RestHttp::parseResult($response);
239:         return PrimitiveConverter::toInteger($count);
240:     }
241: 
242:     /**
243:      * Send domain event to the server. Server will return identity under which it was stored.
244:      * Events can't be modified once they are submitted. Only new events can be created.
245:      *
246:      * @param DomainEvent $event Event to be executed
247:      * @return string Event URI
248:      */
249:     public function submitEvent(DomainEvent $event)
250:     {
251:         $name = Name::full($event);
252:         $response =
253:             $this->http->sendRequest(
254:                 self::DOMAIN_URI.'/submit/'.rawurlencode($name),
255:                 'POST',
256:                 $event->toJson(),
257:                 array(201));
258:         $uri = RestHttp::parseResult($response);
259:         return PrimitiveConverter::toString($uri);
260:     }
261: 
262:     /**
263:      * Apply domain event to a single aggregate. Server will return modified aggregate root.
264:      * Events can't be modified once they are submitted. Only new events can be created.
265:      *
266:      * @param AggregateDomainEvent $event
267:      * @param string $uri URI of aggregate root
268:      * @return \NGS\Patterns\AggregateRoot Aggregate on which event was applied
269:      */
270:     public function submitAggregateEvent(AggregateDomainEvent $event, $uri)
271:     {
272:         $object = Name::parent($event);
273:         $name = Name::base($event);
274:         $response =
275:             $this->http->sendRequest(
276:                 self::DOMAIN_URI.'/submit/'.rawurlencode($object).'/'.rawurlencode($name).'?uri='.rawurlencode($uri),
277:                 'POST',
278:                 $event->toJson(),
279:                 array(201));
280:         Repository::instance()->invalidate($object, $uri);
281:         return RestHttp::parseResult($response, Name::toClass($object));
282:     }
283: 
284: }
285: 
API documentation generated by ApiGen 2.8.0