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__.'/QueryString.php');
  8: 
  9: use NGS\Converter\PrimitiveConverter;
 10: use NGS\Converter\ObjectConverter;
 11: use NGS\Name;
 12: use NGS\Patterns\Specification;
 13: use NGS\Patterns\GenericSearch;
 14: 
 15: /**
 16:  * Proxy service to reporting operations such as document generation,
 17:  * report population and history lookup.
 18:  * Report should be used to minimize calls to server.
 19:  */
 20: class ReportingProxy
 21: {
 22:     const REPORTING_URI = 'Reporting.svc';
 23: 
 24:     protected $http;
 25: 
 26:     protected static $instance;
 27: 
 28:     /**
 29:      * Create a new ReportingProxy instance
 30:      *
 31:      * @param RestHttp $http RestHttp instance used for http request.
 32:      * Optionally specify an instance, otherwise use a singleton instance
 33:      */
 34:     public function __construct(RestHttp $http = null)
 35:     {
 36:         $this->http = $http !== null ? $http : RestHttp::instance();
 37:     }
 38: 
 39:     /**
 40:      * Gets singleton instance of Reporting.svc proxy
 41:      *
 42:      * @return ReportingProxy
 43:      */
 44:     public static function instance()
 45:     {
 46:         if(self::$instance === null)
 47:             self::$instance = new ReportingProxy();
 48:         return self::$instance;
 49:     }
 50: 
 51:     /**
 52:      * Populate report. Send message to server with serialized report specification.
 53:      * @todo: API change, Report/Result
 54:      *
 55:      * @param $report
 56:      * @return mixed
 57:      */
 58:     public function populateReport($report)
 59:     {
 60:         $class = get_class($report);
 61:         $name = Name::full($report);
 62:         $response =
 63:         $this->http->sendRequest(
 64:             self::REPORTING_URI.'/report/'.rawurlencode($name),
 65:             'PUT',
 66:             $report->toJson(),
 67:             array(200));
 68:         return RestHttp::parseResult($response, $class);
 69:     }
 70: 
 71:     /**
 72:      * Create document from report. Send message to server with serialized report specification.
 73:      * Server will return template populated with found data.
 74:      *
 75:      * @param  mixed  $report    Report instance
 76:      * @param  string $templater Templater name
 77:      * @return string            Report contents
 78:      */
 79:     public function createReport($report, $templater)
 80:     {
 81:         $name = Name::full($report);
 82:         return
 83:             $this->http->sendRequest(
 84:                 self::REPORTING_URI.'/report/'.rawurlencode($name).'/'.rawurlencode($templater),
 85:                 'PUT',
 86:                 $report->toJson(),
 87:                 array(201),
 88:                 'application/octet-stream');
 89:     }
 90: 
 91:     /**
 92:      * Perform data analysis on specified data source.
 93:      * Data source is filtered using provided specification.
 94:      * Analysis is performed by grouping data by dimensions
 95:      * and aggregating information using specified facts.
 96:      *
 97:      * @param  \NGS\Patterns\OlapCube      $cube
 98:      * @param  \NGS\Patterns\Specification $specification
 99:      * @param  string                      $templater
100:      * @param  array                       $dimensions
101:      * @param  array                       $facts
102:      * @param  array                       $order
103:      * @return string Report contents
104:      */
105:     public function olapCubeWithSpecification(
106:         $cube,
107:         $specification,
108:         $templater,
109:         array $dimensions,
110:         array $facts,
111:         array $order = array())
112:     {
113:         $cube = Name::full($cube);
114:         $name = Name::base($specification);
115:         $fullName = Name::full($specification);
116:         if(strncmp($fullName, $cube, strlen($cube)) != 0)
117:             $name = substr($fullName, 0, strlen($fullName) - strlen($name) - 1).'+'.$name;
118:         $arguments = QueryString::prepareCubeCall($dimensions, $facts, $order);
119:         return
120:             $this->http->sendRequest(
121:                 self::REPORTING_URI.'/olap/'.rawurlencode($cube).'/'.rawurlencode($templater).'?specification='.rawurlencode($name).'&'.$arguments,
122:                 'PUT',
123:                 $specification->toJson(),
124:                 array(201),
125:                 'application/octet-stream');
126:     }
127: 
128:     /**
129:      * Perform data analysis on specified data source.
130:      * Analysis is performed by grouping data by dimensions
131:      * and aggregating information using specified facts.
132:      *
133:      * @param \NGS\Patterns\OlapCube $cube
134:      * @param  string                      $templater
135:      * @param  array                       $dimensions
136:      * @param  array                       $facts
137:      * @param  array                       $order
138:      * @return string Report contents
139:      */
140:     public function olapCube(
141:         $cube,
142:         $templater,
143:         array $dimensions,
144:         array $facts,
145:         array $order = array())
146:     {
147:         $cube = Name::full($cube);
148:         $arguments = QueryString::prepareCubeCall($dimensions, $facts, $order);
149:         return
150:             $this->http->sendRequest(
151:                 self::REPORTING_URI.'/olap/'.rawurlencode($cube).'/'.rawurlencode($templater).'?'.$arguments,
152:                 'GET',
153:                 null,
154:                 array(201),
155:                 'application/octet-stream');
156:     }
157: 
158:     /**
159:      * Get aggregate root history.
160:      * History is collection of snapshots made at state changes.
161:      *
162:      * @param  string $class Object class name
163:      * @param  string $uri   Object URI
164:      * @return array         List of history entries
165:      */
166:     public function getHistory($class, $uri)
167:     {
168:         return is_array($uri)
169:             ? $this->getCommandHistory($class, $uri)
170:             : $this->getRestHistory($class, $uri);
171:     }
172: 
173:     private static function parseHistoryResponse($response, $class)
174:     {
175:         $data = json_decode($response, true);
176:         $result = array();
177:         $converter = ObjectConverter::getConverter($class, ObjectConverter::ARRAY_TYPE);
178: 
179:         foreach($data as $dataItem)
180:         {
181:             $history = array();
182:             $snapshots = $dataItem['Snapshots'];
183:             foreach($snapshots as $snapshotItem)
184:             {
185:                 $history[] =
186:                     new \NGS\Patterns\Snapshot(
187:                         $snapshotItem['At'],
188:                         $snapshotItem['Action'],
189:                         $converter::fromArray($snapshotItem['Value']));
190:             }
191:             $result[] = $history;
192:         }
193: 
194:         return $result;
195:     }
196: 
197:     private function getCommandHistory($class, $uris)
198:     {
199:         $name = Name::full($class);
200:         $body = array('Name' => $name, 'Uri' => PrimitiveConverter::toStringArray($uris));
201:         $response =
202:             $this->http->sendRequest(
203:                 ApplicationProxy::APPLICATION_URI.'/GetRootHistory',
204:                 'POST',
205:                 json_encode($body),
206:                 array(200));
207:         return self::parseHistoryResponse($response, $class);
208:     }
209: 
210:     private function getRestHistory($class, $uri)
211:     {
212:         $name = Name::full($class);
213:         $response =
214:             $this->http->sendRequest(
215:                 self::REPORTING_URI.'/history/'.rawurlencode($name).'/'.rawurlencode($uri),
216:                 'GET',
217:                 null,
218:                 array(200));
219:         $history = self::parseHistoryResponse($response, $class);
220:         return isset($history[0]) ? $history[0] : array();
221:     }
222: 
223:     /**
224:      * Populate template using found domain object.
225:      * Optionally convert document to pdf.
226:      *
227:      * @param  string $file  Template file to populate
228:      * @param  string $class Object class
229:      * @param  string $uri   Object URI
230:      * @return string        Populated template contents
231:      */
232:     public function findTemplater(
233:         $file,
234:         $class,
235:         $uri=null)
236:     {
237:         $name = Name::full($class);
238:         $uriQuery = $uri!==null ? '/'.$uri : '';
239:         return
240:             $this->http->sendRequest(
241:                 self::REPORTING_URI.'/templater/'.rawurlencode($file).'/'.rawurlencode($name).$uriQuery,
242:                 'GET',
243:                 null,
244:                 array(200),
245:                 'application/octet-stream');
246:     }
247: 
248:     /**
249:      * Populate template using domain objects which satisfy
250:      * {@ses NGS\Patterns\Specification}.
251:      * Optionally convert document to pdf.
252:      *
253:      * @param  string $file  Template file to populate
254:      * @param  \NGS\Patterns\Specification Specification to be searched
255:      * @return string        Populated template contents
256:      */
257:     public function searchTemplater(
258:         $file,
259:         Specification $specification)
260:     {
261:         $object = Name::parent($specification);
262:         $name = Name::base($specification);
263:         return
264:             $this->http->sendRequest(
265:                 self::REPORTING_URI.'/templater/'.rawurlencode($file).'/'.rawurlencode($object).'?specification='.rawurlencode($name),
266:                 'PUT',
267:                 $specification->toJson(),
268:                 array(200),
269:                 'application/octet-stream');
270:     }
271: 
272:     /**
273:      * Populate template using domain objects which satisfy
274:      * {@ses NGS\Patterns\GenericSearch}.
275:      *
276:      * @param  string $file  Template file to populate
277:      * @param  string \NGS\Patterns\GenericSearch
278:      * @return string        Populated template contents
279:      */
280:     public function searchTemplaterGeneric(
281:         $file,
282:         GenericSearch $search)
283:     {
284:         $object = Name::full($search->getObject());
285:         return
286:             $this->http->sendRequest(
287:                 self::REPORTING_URI.'/templater-generic/'.rawurlencode($file).'/'.rawurlencode($object),
288:                 'PUT',
289:                 json_encode($search->getFilters()),
290:                 array(200),
291:                 'application/octet-stream');
292:     }
293: }
294: 
API documentation generated by ApiGen 2.8.0