2 namespace Workspace\Service;
7 * Basic data node to provide global functionality to workflow services.
10 class DataBin extends Workflow
15 const ACTION_TYPE_SESSION = 'Session';
16 const ACTION_TYPE_LIST = 'List';
17 const ACTION_TYPE_SELECT_LIST = 'SelectList';
18 const ACTION_TYPE_GRID = 'Grid';
19 const ACTION_TYPE_VIEW = 'View';
20 const ACTION_TYPE_CREATE = 'Create';
21 const ACTION_TYPE_UPDATE = 'Update';
22 const ACTION_TYPE_DELETE = 'Delete';
23 const ACTION_TYPE_UNDELETE = 'UnDelete';
24 const ACTION_TYPE_PDF = 'Pdf';
25 const ACTION_TYPE_REPORT = 'Report';
29 * @param \Workspace\Workflow $workflowNode
31 public function setWorkflow(\Workspace\Workflow $workflowNode)
33 $this->workflowNode = $workflowNode;
34 $this->em = $this->workflowNode->getEntityManager();
40 * Route contract and execute requests according to meta.
42 * @param array $arguments
44 * @return \Workspace\Contract\AbstractBase|array
46 public function __call($name, $arguments)
48 #-> Is this a contract, execution or direct execution request?
49 if ('contractRoute' == substr($name, 0, 13))
51 #-> Route Contract request, establish action and retrieve meta.
52 $action = substr($name, 13);
53 $meta = 'metaRoute' . $action;
54 if (!isset($this->$meta))
56 throw new \Exception('contractRoute:Requested DataBin routing meta structure not defined.');
59 if (isset($meta['Flags']) && is_array($meta['Flags']))
61 foreach ($meta['Flags'] as $flag => $value)
63 \Utility\Registry::setOnce($flag, $value);
66 return $this->conRoute($meta, $arguments[0], $arguments[1]);
68 elseif ('executeRoute' == substr($name, 0, 12))
70 #-> Route Execution request, establish action and retrieve meta.
71 $action = substr($name, 12);
72 $meta = 'metaRoute' . $action;
74 if (isset($meta['Flags']) && is_array($meta['Flags']))
76 foreach ($meta['Flags'] as $flag => $value)
78 \Utility\Registry::setOnce($flag, $value);
81 return $this->exeRoute($meta, $arguments[0], $arguments[1], $arguments[2]);
83 elseif ('contract' == substr($name, 0, 8))
85 #-> Task Contract request, establish action and retrieve meta.
86 $action = substr($name, 8);
87 $meta = 'meta' . $action;
88 if (!isset($this->$meta))
90 throw new \Exception('contract:Requested DataBin meta structure not defined.');
93 if (isset($meta['Flags']) && is_array($meta['Flags']))
95 foreach ($meta['Flags'] as $flag => $value)
97 \Utility\Registry::setOnce($flag, $value);
109 if (in_array($action, array(
110 'List', 'SelectList', 'Grid', 'View',
111 'Create', 'Update', 'Delete'
114 $meta['Type'] = $action;
116 if (!isset($meta['Type']))
118 throw new \Exception(
119 'DataBin meta structure provided without handling method and no core Type.'
122 switch ($meta['Type'])
124 case self::ACTION_TYPE_SESSION:
125 return $this->conSession($meta, $arguments[0], $arguments[1]);
127 case self::ACTION_TYPE_LIST:
128 return $this->conList($meta, $arguments[0], $arguments[1]);
130 case self::ACTION_TYPE_SELECT_LIST:
131 return $this->conSelectList($meta, $arguments[0], $arguments[1]);
133 case self::ACTION_TYPE_GRID:
134 return $this->conGrid($meta, $arguments[0], $arguments[1]);
136 case self::ACTION_TYPE_VIEW:
137 return $this->conView($meta, $arguments[0], $arguments[1]);
139 case self::ACTION_TYPE_CREATE:
140 return $this->conCreate($meta, $arguments[0], $arguments[1]);
142 case self::ACTION_TYPE_UPDATE:
143 return $this->conUpdate($meta, $arguments[0], $arguments[1]);
145 case self::ACTION_TYPE_DELETE:
146 return $this->conDelete($meta, $arguments[0], $arguments[1]);
148 case self::ACTION_TYPE_UNDELETE:
149 return $this->conUnDelete($meta, $arguments[0], $arguments[1]);
151 case self::ACTION_TYPE_PDF:
152 return $this->conPdf($meta, $arguments[0], $arguments[1]);
154 case self::ACTION_TYPE_REPORT:
155 return $this->conReport($meta, $arguments[0], $arguments[1]);
158 throw new \Exception(
159 'Undefined core Type specified in DataBin meta structure.'
164 elseif ('execute' == substr($name, 0, 7))
166 #-> Task Execution request, establish action and retrieve meta.
167 $action = substr($name, 7);
168 $meta = 'meta' . $action;
169 $meta = $this->$meta;
170 if (isset($meta['Flags']) && is_array($meta['Flags']))
172 foreach ($meta['Flags'] as $flag => $value)
174 \Utility\Registry::setOnce($flag, $value);
177 switch ($meta['Type'])
179 case self::ACTION_TYPE_SESSION:
180 return $this->exeSession($meta, $arguments[0], $arguments[1]);
182 case self::ACTION_TYPE_LIST:
183 return $this->exeList($meta, $arguments[0], $arguments[1]);
185 case self::ACTION_TYPE_SELECT_LIST:
186 return $this->exeSelectList($meta, $arguments[0], $arguments[1]);
188 case self::ACTION_TYPE_GRID:
189 return $this->exeGrid($meta, $arguments[0], $arguments[1]);
191 case self::ACTION_TYPE_VIEW:
192 return $this->exeView($meta, $arguments[0], $arguments[1]);
194 case self::ACTION_TYPE_CREATE:
195 return $this->exeCreate($meta, $arguments[0], $arguments[1]);
197 case self::ACTION_TYPE_UPDATE:
198 return $this->exeUpdate($meta, $arguments[0], $arguments[1]);
200 case self::ACTION_TYPE_DELETE:
201 return $this->exeDelete($meta, $arguments[0], $arguments[1]);
203 case self::ACTION_TYPE_UNDELETE:
204 return $this->exeUnDelete($meta, $arguments[0], $arguments[1]);
206 case self::ACTION_TYPE_PDF:
207 return $this->exePdf($meta, $arguments[0], $arguments[1]);
209 case self::ACTION_TYPE_REPORT:
210 return $this->exeReport($meta, $arguments[0], $arguments[1]);
218 * Contract for session based operation.
220 * @param object|null $jobRecord
221 * @param array $input
222 * @return \Workspace\Contract\AbstractBase
225 public function conSession($meta, $jobRecord, array $input = array())
228 if (isset($this->meta['JobField']) && is_null($jobRecord))
230 throw new \Exception('`JobId` root parameter is required for this contract.');
232 $options = $this->buildOptions($meta);
233 $requirement = $this->buildRequirements($meta);
234 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
235 ? new \Workspace\Contract\Recurring($options, $requirement)
236 : new \Workspace\Contract\UseOnce($options, $requirement);
237 return $this->buildConditions($contract, $meta);
241 * Store data to session.
243 * @param object|null $jobRecord
244 * @param \Workspace\Utility\ServiceInputParams $contract
247 public function exeSession($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
249 #-> Store input to session.
250 $session = new \Zend\Session\Container($meta['Namespace']);
251 !isset($session->options)
252 && $session->options = array();
253 $session->options[] = $contract->options;
254 foreach ($meta['RequiredInput'] as $group => $fields)
256 isset($session->$group)
257 || $session->$group = array();
258 $session->$group = array_merge($session->$group, $contract->data->$group);
260 foreach ($meta['OptionalInput'] as $group => $fields)
262 isset($session->$group)
263 || $session->$group = array();
264 !isset($meta['RequiredInput'][$group])
265 && isset($contract->data->$group)
266 && $session->$group = array_merge($session->$group, $contract->data->$group);
269 #-> Handle post execution actions.
270 if (isset($meta['ExecuteAfter']))
272 foreach ($meta['ExecuteAfter'] as $action)
274 $this->$action($meta, $jobRecord, $session, $contract);
279 return $contract->success('Data stored.');
284 * Contract to route item to a new state.
286 * @param object|null $jobRecord
287 * @param array $input
288 * @return \Workspace\Contract\AbstractBase
291 public function conRoute($meta, $jobRecord, array $input = array())
294 if (isset($meta['RequireAuth'])
295 && true == $meta['RequireAuth']
296 && !\Utility\Registry::isAuthenticated())
298 throw new \Exception('Authentication required for this functionality.');
300 if (isset($this->meta['JobField']) && is_null($jobRecord))
302 throw new \Exception('`JobId` root parameter is required for this contract.');
304 if (isset($meta['Surrogate']))
306 $baseMeta = $meta['Surrogate'];
307 $meta = $this->$baseMeta;
309 $options = $this->buildOptions($meta);
310 $requirement = $this->buildRequirements($meta);
311 $contract = new \Workspace\Contract\UseOnce($options, $requirement);
312 return $this->buildConditions($contract, $meta);
316 * Route item to a new state.
318 * @param object|null $jobRecord
319 * @param string $currentState
320 * @param \Workspace\Utility\ServiceInputParams $contract
324 public function exeRoute($meta, $jobRecord, $currentState, \Workspace\Utility\ServiceInputParams $contract)
326 if (isset($meta['RequireAuth'])
327 && true == $meta['RequireAuth']
328 && !\Utility\Registry::isAuthenticated())
330 throw new \Exception('Authentication required for this functionality.');
332 if (isset($meta['Surrogate']))
334 $baseMeta = $meta['Surrogate'];
335 $surrogate = $this->$baseMeta;
336 switch ($surrogate['Type'])
339 $this->exeList($surrogate, $jobRecord, $contract);
342 $this->exeSelectList($surrogate, $jobRecord, $contract);
345 $this->exeGrid($surrogate, $jobRecord, $contract);
348 $this->exeView($surrogate, $jobRecord, $contract);
351 $this->exeCreate($surrogate, $jobRecord, $contract);
354 $this->exeUpdate($surrogate, $jobRecord, $contract);
357 throw new \Exception('Route may not surrogate Delete functionality.');
362 'Destination' => $meta['Destination'],
363 'Data' => isset($contract->data->Context)
364 ? $contract->data->Context
371 * Contract to list entries.
373 * @param object|null $jobRecord
374 * @param array $input
375 * @return \Workspace\Contract\AbstractBase
378 public function conList($meta, $jobRecord, array $input = array())
381 if (isset($meta['RequireAuth'])
382 && true == $meta['RequireAuth']
383 && !\Utility\Registry::isAuthenticated())
385 throw new \Exception('Authentication required for this functionality.');
387 if (isset($this->meta['JobField']) && is_null($jobRecord))
389 throw new \Exception('`JobId` root parameter is required for this contract.');
391 $options = $this->buildOptions($meta);
392 $requirement = $this->buildRequirements($meta);
393 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
394 ? new \Workspace\Contract\Recurring($options, $requirement)
395 : new \Workspace\Contract\UseOnce($options, $requirement);
396 return $this->buildConditions($contract, $meta);
400 * List entries with optional filtering. Will exclude archived entries by default.
402 * @param object|null $jobRecord
403 * @param \Workspace\Utility\ServiceInputParams $contract
407 public function exeList($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
410 if (isset($meta['RequireAuth'])
411 && true == $meta['RequireAuth']
412 && !\Utility\Registry::isAuthenticated())
414 throw new \Exception('Authentication required for this functionality.');
416 $baseEntity = $this->meta['Entity'];
418 if (isset($this->meta['JobField']))
420 $criteria[$this->meta['JobField']] = $jobRecord->id;
422 isset($contract->data->Filter)
423 && is_array($contract->data->Filter)
424 && !empty($contract->data->Filter)
425 && $criteria = array_merge($criteria, $contract->data->Filter);
426 isset($meta['Filter'])
427 && is_array($meta['Filter'])
428 && !empty($meta['Filter'])
429 && $criteria = array_merge($criteria, $meta['Filter']);
430 $orderBy = !empty($meta['OrderBy'])
433 $expand = isset($meta['Expand'])
438 return $contract->success(
440 $this->dataList($meta['Fields'], $expand, $criteria, $orderBy)
445 * List entries with optional filtering. Will exclude archived entries by default.
446 * @param array $fields
447 * @param array $expand
448 * @param array $criteria
451 public function dataList(array $fields, array $expand = array(), array $criteria = array(), $orderBy = array())
454 $baseEntity = $this->meta['Entity'];
456 && !isset($criteria['archived'])
457 && $criteria['archived'] = false;
458 $records = !empty($criteria)
459 ? $this->em->getRepository($this->meta['Entity'])
460 ->findBy($criteria, $orderBy)
461 : $this->em->getRepository($this->meta['Entity'])
462 ->findBy(array(), $orderBy);
465 foreach ($records as $rowId => $record)
467 $records[$rowId] = $record->toArray($expand, $fields);
476 * Contract to list entries in id => label format. Will exclude archived entries by default.
478 * @param object|null $jobRecord
479 * @param array $input
480 * @return \Workspace\Contract\AbstractBase
483 public function conSelectList($meta, $jobRecord, array $input = array())
486 if (isset($meta['RequireAuth'])
487 && true == $meta['RequireAuth']
488 && !\Utility\Registry::isAuthenticated())
490 throw new \Exception('Authentication required for this functionality.');
492 if (isset($this->meta['JobField']) && is_null($jobRecord))
494 throw new \Exception('`JobId` root parameter is required for this contract.');
496 $options = $this->buildOptions($meta);
497 $requirement = $this->buildRequirements($meta);
498 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
499 ? new \Workspace\Contract\Recurring($options, $requirement)
500 : new \Workspace\Contract\UseOnce($options, $requirement);
501 return $this->buildConditions($contract, $meta);
505 * List entries in id => label format with optional filtering. Will exclude archived entries by default.
507 * @param object|null $jobRecord
508 * @param \Workspace\Utility\ServiceInputParams $contract
512 public function exeSelectList($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
515 if (isset($meta['RequireAuth'])
516 && true == $meta['RequireAuth']
517 && !\Utility\Registry::isAuthenticated())
519 throw new \Exception('Authentication required for this functionality.');
521 $base = $this->meta['Base'];
522 $baseEntity = $this->meta['Entity'];
525 && $criteria['archived'] = false;
526 if (isset($this->meta['JobField']) && !is_null($jobRecord))
528 $criteria[$this->meta['JobField']] = $jobRecord->id;
530 isset($contract->data->Filter)
531 && is_array($contract->data->Filter)
532 && !empty($contract->data->Filter)
533 && $criteria = array_merge($criteria, $contract->data->Filter);
534 isset($meta['Filter'])
535 && is_array($meta['Filter'])
536 && !empty($meta['Filter'])
537 && $criteria = array_merge($criteria, $meta['Filter']);
540 return $contract->success(
543 $meta['Label']['Format'],
544 $meta['Label']['Fields'],
551 * List entries in id => label format with optional filtering. Will exclude archived entries by default.
552 * @param string $labelFormat
553 * @param array $labelFields
554 * @param array $criteria
557 public function selectList($labelFormat, array $labelFields, array $criteria = array())
560 $baseEntity = $this->meta['Entity'];
562 && !isset($criteria['archived'])
563 && $criteria['archived'] = false;
564 $negCriteria = array();
565 foreach ($criteria as $field => $value)
567 if (!is_array($value) && !is_object($value) && '!=' == substr($value, 0, 2))
569 $negCriteria[$field] = substr($value, 2);
570 unset($criteria[$field]);
574 if (isset($labelFields[0]))
576 $orderBy[$labelFields[0]] = 'ASC';
578 $records = !empty($criteria)
579 ? $this->em->getRepository($this->meta['Entity'])
580 ->findBy($criteria, $orderBy)
581 : $this->em->getRepository($this->meta['Entity'])
582 ->findBy(array(), $orderBy);
586 foreach ($labelFields as $key => $fieldName)
589 && $fieldName = $key;
590 $search[] = '[' . $fieldName . ']';
595 foreach ($records as $rowId => $record)
597 foreach ($negCriteria as $field => $value)
599 if ($value == $record->$field)
605 foreach ($labelFields as $key => $fieldName)
608 && $fieldName = $key;
609 $replace[] = !is_numeric($key)
610 ? (!is_null($record->$key) ? $record->$key : $fieldName)
611 : $record->$fieldName;
614 'value' => $record->id,
615 'label' => str_replace(
620 unset($records[$rowId]);
629 * Contract for data grid.
631 * @param object|null $jobRecord
632 * @param array $input
633 * @return \Workspace\Contract\AbstractBase
636 public function conGrid($meta, $jobRecord, array $input = array())
639 if (isset($meta['RequireAuth'])
640 && true == $meta['RequireAuth']
641 && !\Utility\Registry::isAuthenticated())
643 throw new \Exception('Authentication required for this functionality.');
645 /* if (isset($this->meta['JobField']) && is_null($jobRecord))
647 throw new \Exception('`JobId` root parameter is required for this contract.');
649 $options = $this->buildOptions($meta);
650 $requirement = $this->buildRequirements($meta);
651 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
652 ? new \Workspace\Contract\Recurring($options, $requirement)
653 : new \Workspace\Contract\UseOnce($options, $requirement);
654 return $this->buildConditions($contract, $meta);
658 * List entries with optional filtering. Will exclude archived entries by default.
660 * @param object|null $jobRecord
661 * @param \Workspace\Utility\ServiceInputParams $contract
665 public function exeGrid($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
668 if (isset($meta['RequireAuth'])
669 && true == $meta['RequireAuth']
670 && !\Utility\Registry::isAuthenticated())
672 throw new \Exception('Authentication required for this functionality.');
674 $base = $this->meta['Base'];
675 $baseEntity = $this->meta['Entity'];
677 if (isset($this->meta['JobField']) && !is_null($jobRecord))
679 $meta['Filter'][$this->meta['JobField']] = $jobRecord->id;
684 $session = new \Zend\Session\Container('DataBin_Grid_' . $contract->hash);
685 if (\Utility\Registry::initSessionStorage('DataBin_Grid_' . $contract->hash))
687 $session->Filter = array();
688 $session->OrderBy = isset($meta['OrderBy'])
692 $session->NumberOfRecords = $meta['NumberOfRecords'];
696 !isset($session->Filter)
697 && $session->Filter = array();
698 !isset($session->NumberOfRecords)
699 && $session->NumberOfRecords = $meta['NumberOfRecords'];
700 !isset($session->Page)
701 && $session->Page = 1;
702 !isset($session->OrderBy)
703 && $session->OrderBy = isset($meta['OrderBy'])
707 isset($contract->data->Grid['NumberOfRecords'])
708 && is_numeric($contract->data->Grid['NumberOfRecords'])
709 && $session->NumberOfRecords = $contract->data->Grid['NumberOfRecords'];
710 isset($contract->data->Grid['Page'])
711 && is_numeric($contract->data->Grid['Page'])
712 && $session->Page = $contract->data->Grid['Page'];
713 isset($contract->data->Grid['Filter'])
714 && is_array($contract->data->Grid['Filter'])
715 && $session->Filter = $contract->data->Grid['Filter'];
716 isset($contract->data->Grid['OrderBy'])
717 && is_array($contract->data->Grid['OrderBy'])
718 && $session->OrderBy = $contract->data->Grid['OrderBy'];
721 $export = ( isset($meta['Export'])
723 && isset($contract->options->ExportToExcel)
724 && $contract->options->ExportToExcel )
727 if ($export && isset($meta['ExportMeta']))
729 $swap = $meta['ExportMeta'];
730 foreach ($swap as $key => $item)
735 $response = $this->grid(
738 $session->NumberOfRecords,
745 isset($meta['GroupBy'])
755 $response['Meta']['Filters'] = $session->Filter;
757 #-> Check if an excel export is allowed and requested.
760 #-> Build excel report.
761 $reportService = $meta['Builder'];
762 $report = new $reportService();
763 $report->process(array(), array(), $response['DataSet']);
764 $reportWriter = $meta['Writer'];
767 $output = isset($meta['Output'])
770 if ('Download' == $output)
772 $writer = new $reportWriter($report);
776 elseif ('File' == $output)
778 $writer = new $reportWriter($report);
779 $writer->output($meta['FilePath']);
780 return $contract->success('Report saved to file.');
782 elseif ('Raw' == $output)
784 return $contract->success('Report Generated', array(
785 'Title' => $report->getTitle(),
786 'Description' => $report->getDescription(),
787 'QueryDetails' => $report->getQueries(),
788 'Headers' => $report->getHeaders(),
789 'Fields' => $report->getFields(),
790 'TotalFields' => $report->getTotalFields(),
791 'Notes' => $report->getNotes(),
792 'Data' => $report->getDataIntersection()
797 $writer = new $reportWriter($report);
798 return $contract->success('Report Generated', $writer->output());
803 return $contract->success('Grid retrieved.', $response);
807 * Retrieve data grid from provided query.
808 * The DQL query should contain [WHERE] and [ORDER] for relevant hydration.
809 * Filtering allows for smart filtering: 'profile.firstName' => '!NULL'.
810 * numberOfRecords AND page must be greater than 0 to collect a paged dataset.
813 * @param string $selection
814 * @param integer $numberOfRecords
815 * @param integer $page
816 * @param array $filter
817 * @param array $order
818 * @param array $fields
821 public function grid($dql, $selection, $numberOfRecords, $page,
822 array $filter = array(), array $order = array(), $group = '',
823 array $fields = array(), $baseTable = '', $forExport = false, $swap = '')
825 #-> Establish size of dataset.
827 && $group = 'GROUP BY ' . $group;
828 $where = \Utility\Doctrine::dqlFilter($filter, $baseTable);
829 $query = str_replace(
830 array('[SELECTION]', '[WHERE]', '[ORDER]', '[GROUP]', '[SWAP]'),
831 array("COUNT(DISTINCT $baseTable.id) AS total", $where['Where'], '', ''),
834 /* if ('development' == \Utility\Registry::getConfigParam('Instance')) //1517 == \Utility\Registry::getAuthParam('id'))
836 \Utility\Debug::errorLog('----------------------', '----------------------');
837 \Utility\Debug::errorLog('----------------------', '----------------------');
838 \Utility\Debug::errorLog('----------------------', '----------------------');
839 \Utility\Debug::errorLog('GRID COUNT QUERY', $query);
840 \Utility\Debug::errorLog('GRID COUNT PARAMS', $where['Params']);
842 $query = $this->em->createQuery($query);
843 !empty($where['Params'])
844 && $query->setParameters($where['Params']);
845 //\Utility\Debug::errorLog('COUNT', $query->getSQL());
846 $numRecsRes = $query->getSingleResult();
847 $numRecs = (int) $numRecsRes['total'];
848 if (0 == $numberOfRecords)
850 $numPages = (0 < $numRecs)
856 $numPages = (0 < $numRecs)
857 ? ceil($numRecs / $numberOfRecords)
861 #-> Retrieve paged dataset.
862 $query = str_replace(
863 array('[SELECTION]', '[WHERE]', '[ORDER]', '[GROUP]', '[SWAP]'),
864 array($selection, $where['Where'], \Utility\Doctrine::dqlOrder($order), $group, $swap),
867 /* if ('development' == \Utility\Registry::getConfigParam('Instance'))
869 \Utility\Debug::errorLog('----------------------', '----------------------');
870 \Utility\Debug::errorLog('GRID QUERY', $query);
871 \Utility\Debug::errorLog('GRID PARAMS', $where['Params']);
873 $query = $this->em->createQuery($query);
874 !empty($where['Params'])
875 && $query->setParameters($where['Params']);
878 (0 < $numberOfRecords)
879 && $query->setMaxResults($numberOfRecords);
880 (0 < $page && 0 < $numberOfRecords)
881 && $query->setFirstResult(($page - 1) * $numberOfRecords);
883 // \Utility\Debug::errorLog('QUERY', $query->getSQL());
884 // \Utility\Debug::errorLog('PARAMS', $query->getParameters());
885 /* if ('development' == \Utility\Registry::getConfigParam('Instance'))
887 \Utility\Debug::errorLog('----------------------', '----------------------');
888 \Utility\Debug::errorLog('GRID DATA', $query->getArrayResult());
892 'TotalRecords' => $numRecs,
893 'TotalPages' => $numPages,
894 'CurrentPage' => $page,
895 'Filters' => $filter,
898 'DataSet' => (!$forExport
899 ? \Utility\Doctrine::extractData($fields, $query->getArrayResult())
900 : $query->getScalarResult())
906 * Contract to create new entry.
908 * @param object|null $jobRecord
909 * @param array $input
910 * @return \Workspace\Contract\AbstractBase
913 public function conCreate($meta, $jobRecord, array $input = array())
916 if (isset($meta['RequireAuth'])
917 && true == $meta['RequireAuth']
918 && !\Utility\Registry::isAuthenticated())
920 throw new \Exception('Authentication required for this functionality.');
922 if (isset($this->meta['JobField']) && is_null($jobRecord))
924 throw new \Exception('`JobId` root parameter is required for this contract.');
926 $options = $this->buildOptions($meta);
927 $requirement = $this->buildRequirements($meta);
928 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
929 ? new \Workspace\Contract\Recurring($options, $requirement)
930 : new \Workspace\Contract\UseOnce($options, $requirement);
931 return $this->buildConditions($contract, $meta);
937 * @param object|null $jobRecord
938 * @param \Workspace\Utility\ServiceInputParams $contract
942 public function exeCreate($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
944 #-> Context data publication.
945 if (isset($meta['RequireAuth'])
946 && true == $meta['RequireAuth']
947 && !\Utility\Registry::isAuthenticated())
949 throw new \Exception('Authentication required for this functionality.');
951 isset($contract->data->Context)
952 && \Utility\Registry::setOnce(
953 'Service.' . $this->meta['Base'] . '.Context',
954 $contract->data->Context
958 $base = $this->meta['Base'];
959 $data = $contract->data;
960 if (isset($meta['ExecuteBefore']))
962 foreach ($meta['ExecuteBefore'] as $action)
964 $data = $this->$action($meta, $data);
967 $data = $data->$base;
971 if (isset($meta['RelatedEntityFromInput']))
973 foreach ($meta['RelatedEntityFromInput'] as $context => $relation)
975 $workflow = $relation['Workflow'];
976 $service = $relation['Service'];
977 $service = new $service();
978 $service->setWorkflow(new $workflow());
979 $relId = $service->create($contract->data->$context)->id;
980 $data[$relation['Field']] = $relId;
983 if (isset($this->meta['JobField']))
985 $data[$this->meta['JobField']] = $jobRecord->id;
987 $record = $this->create($data);
989 #-> Handle post execution actions.
991 if (isset($meta['ExecuteAfter']))
993 foreach ($meta['ExecuteAfter'] as $action)
995 $feed = $this->$action($meta, $jobRecord, $record, $contract);
1000 return $contract->success('Entry created.', array(
1001 'id' => $record->id,
1007 * Create a new entry.
1008 * @param array $data
1011 public function create(array $data)
1014 $base = $this->meta['Base'];
1015 $baseEntity = $this->meta['Entity'];
1016 if (isset($this->meta['References']) && !empty($this->meta['References']))
1018 foreach ($this->meta['References'] as $field => $entity)
1020 isset($data[$field])
1021 && $data[$field] = $this->em->getReference($entity, $data[$field]);
1024 $record = new $baseEntity();
1025 $record->fromArray($data);
1026 $this->em->persist($record);
1029 #-> Check for post-create requirement.
1030 if (defined($baseEntity . '::HAVE_POST_INSERT'))
1032 $record->postInsert();
1036 #-> Broadcast the data change.
1037 /*switch ($baseEntity::PUSH_SYNCH_STRATEGY)
1040 \Utility\Comms\Ape::broadcastBuildDatasetChange($this->meta['DatasetName']);
1043 if (defined($baseEntity . '::JOB_QUEUE'))
1045 if (1 != $record->queueStatus)
1050 \Utility\Comms\Ape::broadcastUpdateDatasetChange(
1051 $this->meta['DatasetName'],
1052 \Utility\Comms\Ape::CHANGE_TYPE_CREATE,
1053 array($record->toSynchArray())
1057 \Utility\Event::trigger($this->meta['Base'] . '.Create', $record);
1063 * Contract to view an entry.
1064 * @param array $meta
1065 * @param object|null $jobRecord
1066 * @param array $input
1067 * @return \Workspace\Contract\AbstractBase
1068 * @throws \Exception
1070 public function conView($meta, $jobRecord, array $input = array())
1073 if (isset($meta['RequireAuth'])
1074 && true == $meta['RequireAuth']
1075 && !\Utility\Registry::isAuthenticated())
1077 throw new \Exception('Authentication required for this functionality.');
1079 if (isset($this->meta['JobField']) && is_null($jobRecord))
1081 throw new \Exception('`JobId` root parameter is required for this contract.');
1083 if (!isset($input['id']) || !is_numeric($input['id']) || 0 == $input['id'])
1085 throw new \Exception('A valid record `id` is required to setup the contract.');
1087 $base = $this->meta['Base'];
1089 ->getRepository($this->meta['Entity'])
1090 ->find($input['id']);
1091 if (is_null($record))
1093 throw new \Exception('Could not find record.');
1095 if (isset($this->meta['JobField']))
1097 $field = $this->meta['JobField'];
1098 if ($record->$field->id != $jobRecord->id)
1100 throw new \Exception('This record does not belong to the specified JobId.');
1105 $contract = new \Workspace\Contract\Recurring(
1106 new \Workspace\UseCase\Options(),
1107 new \Workspace\UseCase\Requirement()
1109 return $contract->setData($record->toArray(
1110 is_array($meta) && isset($meta['Expand'])
1113 is_array($meta) && isset($meta['Intersect'])
1114 ? $meta['Intersect']
1117 isset($meta['ExpandDepth'])
1118 ? $meta['ExpandDepth']
1125 * @param array $meta
1126 * @param object|null $jobRecord
1127 * @param \Workspace\Utility\ServiceInputParams $contract
1129 * @throws \Exception
1131 public function exeView(array $meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1134 if (isset($meta['RequireAuth'])
1135 && true == $meta['RequireAuth']
1136 && !\Utility\Registry::isAuthenticated())
1138 throw new \Exception('Authentication required for this functionality.');
1140 return $contract->success('Entry retrieved.', $this->view(
1141 $contract->data->id,
1142 isset($meta['Expand'])
1145 isset($meta['Intersect'])
1146 ? $meta['Intersect']
1149 isset($meta['ExpandDepth'])
1150 ? $meta['ExpandDepth']
1157 * @param integer $id
1158 * @param array $expand
1159 * @param array $intersect
1160 * @param boolean $showIdentifiers
1161 * @param integer $expandAll
1164 public function view(
1165 $id, array $expand = array(), array $intersect = array(),
1166 $showIdentifiers = false, $expandAll = 1
1170 $record = $this->em->getReference($this->meta['Entity'], $id);
1171 return $record->toArray($expand, $intersect, $showIdentifiers, $expandAll);
1176 * Contract to update an entry.
1177 * @param array $meta
1178 * @param object|null $jobRecord
1179 * @param array $input
1180 * @return \Workspace\Contract\AbstractBase
1181 * @throws \Exception
1183 public function conUpdate($meta, $jobRecord, array $input = array())
1186 if (isset($meta['RequireAuth'])
1187 && true == $meta['RequireAuth']
1188 && !\Utility\Registry::isAuthenticated())
1190 throw new \Exception('Authentication required for this functionality.');
1192 if (isset($this->meta['JobField']) && is_null($jobRecord))
1194 throw new \Exception('`JobId` root parameter is required for this contract.');
1196 if (!isset($input['id']) || !is_numeric($input['id']) || 0 == $input['id'])
1198 throw new \Exception('A valid record `id` parameter in the `Packet` root is required to setup the contract.');
1200 $base = $this->meta['Base'];
1202 ->getRepository($this->meta['Entity'])
1203 ->find($input['id']);
1204 if (is_null($record))
1206 throw new \Exception('Could not find record.');
1208 if (isset($this->meta['JobField']))
1210 $field = $this->meta['JobField'];
1211 if ($record->$field->id != $jobRecord->id)
1213 throw new \Exception('This record does not belong to the specified JobId.');
1218 $options = $this->buildOptions($meta);
1219 $requirement = $this->buildRequirements($meta);
1220 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
1221 ? new \Workspace\Contract\Recurring($options, $requirement)
1222 : new \Workspace\Contract\UseOnce($options, $requirement);
1223 $contract = $this->buildConditions($contract, $meta);
1225 #-> Handle additional contract.
1226 if (isset($meta['ConditionalContract']))
1228 foreach ($meta['ConditionalContract'] as $action)
1230 $this->$action($meta, $jobRecord, $record, $contract);
1235 $expand = isset($meta['Expand'])
1238 return $contract->setData($record->toArray($expand, array(), true));
1243 * @param array $meta
1244 * @param object|null $jobRecord
1245 * @param \Workspace\Utility\ServiceInputParams $contract
1247 * @throws \Exception
1249 public function exeUpdate($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1251 #-> Context data publication.
1252 if (isset($meta['RequireAuth'])
1253 && true == $meta['RequireAuth']
1254 && !\Utility\Registry::isAuthenticated())
1256 throw new \Exception('Authentication required for this functionality.');
1258 isset($contract->data->Context)
1259 && \Utility\Registry::setOnce(
1260 'Service.' . $this->meta['Base'] . '.Context',
1261 $contract->data->Context
1264 #-> Handle related entity updates.
1265 $base = $this->meta['Base'];
1267 $data = isset($contract->data->$base)
1268 ? $contract->data->$base
1270 if (isset($meta['ExecuteBefore']))
1272 foreach ($meta['ExecuteBefore'] as $action)
1274 $res = $this->$action($meta, $jobRecord, $contract, $data);
1275 if (is_object($res))
1277 $contract->data = $res;
1278 $data = isset($contract->data->$base)
1279 ? $contract->data->$base
1288 if (isset($meta['RelatedEntityFromInput']))
1290 $record = $this->em->getRepository($this->meta['Entity'])
1291 ->find($contract->data->id);
1292 foreach ($meta['RelatedEntityFromInput'] as $context => $relation)
1294 $workflow = $relation['Workflow'];
1295 $service = $relation['Service'];
1296 $field = $relation['Field'];
1297 $service = new $service();
1298 $service->setWorkflow(new $workflow());
1299 if (!is_null($record->$field))
1302 $record->$field->id,
1303 $contract->data->$context
1308 $relId = $service->create($contract->data->$context)->id;
1309 $data[$field] = $relId;
1316 && $record = $this->update(
1317 $contract->data->id, $data, $record
1320 #-> Handle post execution actions.
1322 if (isset($meta['ExecuteAfter']))
1325 && $record = $this->em->getRepository($this->meta['Entity'])
1326 ->find($contract->data->id);
1327 foreach ($meta['ExecuteAfter'] as $action)
1329 $feed = $this->$action($meta, $jobRecord, $record, $contract);
1334 return $contract->success('Entry updated.', array(
1335 'id' => !is_null($record) ? $record->id : $contract->data->id,
1342 * @param integer $id
1343 * @param array $data
1344 * @param object|null $record
1347 public function update($id, array $data, $record = null)
1350 $base = $this->meta['Base'];
1351 $baseEntity = $this->meta['Entity'];
1352 $record = is_null($record)
1353 ? $this->em->getRepository($this->meta['Entity'])
1356 defined($baseEntity . '::JOB_QUEUE')
1357 && $queueStatus = $record->queueStatus;
1358 if (isset($this->meta['References']) && !empty($this->meta['References']))
1360 foreach ($this->meta['References'] as $field => $entity)
1362 $data[$field] = isset($data[$field]) && !empty($data[$field])
1363 ? $this->em->getReference($entity, $data[$field])
1367 $record->fromArray($data);
1370 #-> Check for post-update requirement.
1371 if (defined($baseEntity . '::HAVE_POST_UPDATE'))
1373 $record->postUpdate();
1377 #-> Broadcast the data change.
1378 /*switch ($baseEntity::PUSH_SYNCH_STRATEGY)
1381 \Utility\Comms\Ape::broadcastBuildDatasetChange($this->meta['DatasetName']);
1384 $type = \Utility\Comms\Ape::CHANGE_TYPE_UPDATE;
1385 $updateData = $record->toSynchArray();
1386 if (defined($baseEntity . '::JOB_QUEUE'))
1388 if (1 != $record->queueStatus
1389 && 1 != $queueStatus)
1395 if ($record->queueStatus == $queueStatus)
1397 $type = \Utility\Comms\Ape::CHANGE_TYPE_UPDATE;
1399 elseif (0 == $queueStatus)
1401 $type = \Utility\Comms\Ape::CHANGE_TYPE_CREATE;
1405 $type = \Utility\Comms\Ape::CHANGE_TYPE_DELETE;
1406 $updateData = array('id' => $record->id);
1410 \Utility\Comms\Ape::broadcastUpdateDatasetChange(
1411 $this->meta['DatasetName'],
1417 \Utility\Event::trigger($this->meta['Base'] . '.Update', $record);
1423 * Contract to delete an entry.
1424 * @param array $meta
1425 * @param object|null $jobRecord
1426 * @param array $input
1427 * @return \Workspace\Contract\AbstractBase
1428 * @throws \Exception
1430 public function conDelete($meta, $jobRecord, array $input = array())
1433 if (isset($meta['RequireAuth'])
1434 && true == $meta['RequireAuth']
1435 && !\Utility\Registry::isAuthenticated())
1437 throw new \Exception('Authentication required for this functionality.');
1439 if (isset($this->meta['JobField']) && is_null($jobRecord))
1441 throw new \Exception('`JobId` root parameter is required for this contract.');
1443 if (!isset($input['id']) || !is_numeric($input['id']) || 0 == $input['id'])
1445 throw new \Exception('A valid record `id` is required to setup the contract.');
1447 $base = $this->meta['Base'];
1449 ->getRepository($this->meta['Entity'])
1450 ->find($input['id']);
1451 if (is_null($record))
1453 throw new \Exception('Could not find record.');
1455 if (isset($this->meta['JobField']))
1457 $field = $this->meta['JobField'];
1458 if ($record->$field->id != $jobRecord->id)
1460 throw new \Exception('This record does not belong to the specified JobId.');
1465 $options = $this->buildOptions($meta);
1466 $requirement = $this->buildRequirements($meta);
1467 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
1468 ? new \Workspace\Contract\Recurring($options, $requirement)
1469 : new \Workspace\Contract\UseOnce($options, $requirement);
1470 $contract = $this->buildConditions($contract, $meta);
1471 return $contract->setData($record->toArray(array(), array(), true));
1476 * @param array $meta
1477 * @param object|null $jobRecord
1478 * @param \Workspace\Utility\ServiceInputParams $contract
1480 * @throws \Exception
1482 public function exeDelete($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1484 #-> Context data publication.
1485 if (isset($meta['RequireAuth'])
1486 && true == $meta['RequireAuth']
1487 && !\Utility\Registry::isAuthenticated())
1489 throw new \Exception('Authentication required for this functionality.');
1491 isset($contract->data->Context)
1492 && \Utility\Registry::setOnce(
1493 'Service.' . $this->meta['Base'] . '.Context',
1494 $contract->data->Context
1498 $record = $this->em->getRepository($this->meta['Entity'])
1499 ->find($contract->data->id);
1500 $base = $this->meta['Base'];
1501 $data = isset($contract->data->$base)
1502 ? $contract->data->$base
1504 if (isset($meta['ExecuteBefore']))
1506 foreach ($meta['ExecuteBefore'] as $action)
1508 $data = $this->$action($meta, $record, $contract, $data);
1512 #-> Handle related entity updates.
1513 if (isset($meta['RelatedEntityFromInput']))
1515 foreach ($meta['RelatedEntityFromInput'] as $context => $relation)
1517 $workflow = $relation['Workflow'];
1518 $service = $relation['Service'];
1519 $field = $relation['Field'];
1520 $service = new $service();
1521 $service->setWorkflow(new $workflow());
1522 $service->delete($record->$field->id);
1526 #-> Delete/Archive entry.
1527 $this->delete($contract->data->id, $record);
1529 #-> Handle post execution actions.
1530 if (isset($meta['ExecuteAfter']))
1532 foreach ($meta['ExecuteAfter'] as $action)
1534 $this->$action($meta, $jobRecord, $record, $contract);
1539 return $contract->success('Entry deleted.', array(
1540 'id' => $contract->data->id
1546 * @param integer $id
1547 * @param object|null $record
1550 public function delete($id, $record = null)
1552 #-> Delete/Archive entry.
1553 $base = $this->meta['Base'];
1554 $baseEntity = $this->meta['Entity'];
1555 $record = is_null($record)
1556 ? $this->em->getReference($this->meta['Entity'], $id)
1558 if ($baseEntity::ARCHIVE)
1560 $record->archived = true;
1564 $this->em->remove($record);
1568 #-> Broadcast the data change.
1569 /*switch ($baseEntity::PUSH_SYNCH_STRATEGY)
1572 \Utility\Comms\Ape::broadcastBuildDatasetChange($this->meta['DatasetName']);
1575 if (defined($baseEntity . '::JOB_QUEUE'))
1577 $record = $this->em->getRepository($this->meta['Entity'])
1579 if (1 != $record->queueStatus)
1584 \Utility\Comms\Ape::broadcastUpdateDatasetChange(
1585 $this->meta['DatasetName'],
1586 \Utility\Comms\Ape::CHANGE_TYPE_DELETE,
1587 array(array('id' => $id))
1591 \Utility\Event::trigger($this->meta['Base'] . '.Delete', $record);
1597 * Contract to undelete an entry.
1598 * @param array $meta
1599 * @param object|null $jobRecord
1600 * @param array $input
1601 * @return \Workspace\Contract\AbstractBase
1602 * @throws \Exception
1604 public function conUnDelete($meta, $jobRecord, array $input = array())
1606 #-> Check permissions.
1607 $this->checkPermissions($meta);
1610 if (isset($this->meta['JobField']) && is_null($jobRecord))
1612 throw new \Exception('`JobId` root parameter is required for this contract.');
1614 if (!isset($input['id']) || !is_numeric($input['id']) || 0 == $input['id'])
1616 throw new \Exception('A valid record `id` is required to setup the contract.');
1618 $entityName = '\\' == substr($this->meta['Entity'], 0, 1)
1619 ? substr($this->meta['Entity'], 1)
1620 : $this->meta['Entity'];
1622 ->getRepository($entityName)
1623 ->find($input['id']);
1624 if (is_null($record))
1626 throw new \Exception('Could not find record.');
1628 if (isset($this->meta['JobField']))
1630 $field = $this->meta['JobField'];
1631 if ($record->$field->id != $jobRecord->id)
1633 throw new \Exception('This record does not belong to the specified JobId.');
1638 $options = $this->buildOptions($meta);
1639 $requirement = $this->buildRequirements($meta);
1640 $contract = (isset($meta['Contract']) && self::CONTRACT_TYPE_RECCURING == $meta['Contract'])
1641 ? new \Workspace\Contract\Recurring($options, $requirement)
1642 : new \Workspace\Contract\UseOnce($options, $requirement);
1643 $contract = $this->buildConditions($contract, $meta);
1644 return $contract->setData($record->toArray(array(), array(), true));
1648 * UnDelete an entry.
1649 * @param array $meta
1650 * @param object|null $jobRecord
1651 * @param \Workspace\Utility\ServiceInputParams $contract
1654 public function exeUnDelete($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1656 #-> Context data publication.
1657 isset($contract->data->Context)
1658 && \Utility\Registry::setOnce(
1659 'Service.' . $this->meta['Base'] . '.Context',
1660 $contract->data->Context
1663 #-> Handle related entity updates.
1664 $entityName = '\\' == substr($this->meta['Entity'], 0, 1)
1665 ? substr($this->meta['Entity'], 1)
1666 : $this->meta['Entity'];
1667 $record = $this->em->getRepository($entityName)->find($contract->data->id);
1668 if (isset($meta['RelatedEntityFromInput']))
1670 foreach ($meta['RelatedEntityFromInput'] as $context => $relation)
1672 $workflow = $relation['Workflow'];
1673 $service = $relation['Service'];
1674 $field = $relation['Field'];
1675 $service = new $service();
1676 $service->setWorkflow(\Utility\Registry::getServiceManager()->get($workflow));
1677 $service->undelete($record->$field->id);
1681 #-> Delete/Archive entry.
1682 $this->undelete($contract->data->id, $record);
1684 #-> Handle post execution actions.
1685 if (isset($meta['ExecuteAfter']))
1687 foreach ($meta['ExecuteAfter'] as $action)
1689 $this->$action($meta, $jobRecord, $record, $contract);
1694 return $contract->success('Entry deleted.', array(
1695 'id' => $contract->data->id
1700 * UnDelete an entry.
1701 * @param integer $id
1702 * @param object|null $record
1705 public function undelete($id, $record = null)
1707 #-> Delete/Archive entry.
1708 $base = $this->meta['Base'];
1709 $baseEntity = $this->meta['Entity'];
1711 $record = $this->em->getRepository($this->meta['Entity'])->find($id);
1712 $record->archived = false;
1716 $base = $this->meta['Base'];
1718 #-> Broadcast the data change.
1719 /*switch ($baseEntity::PUSH_SYNCH_STRATEGY)
1722 \Utility\Comms\Ape::broadcastBuildDatasetChange($this->meta['DatasetName']);
1725 if (defined($baseEntity . '::JOB_QUEUE'))
1727 $record = $this->em->getRepository($this->meta['Entity'])
1729 if (1 != $record->queueStatus)
1734 \Utility\Comms\Ape::broadcastUpdateDatasetChange(
1735 $this->meta['DatasetName'],
1736 \Utility\Comms\Ape::CHANGE_TYPE_UNDELETE,
1737 array(array('id' => $id))
1741 $action = $baseEntity::ARCHIVE
1744 \Utility\Event::trigger($this->meta['Base'] . $action, $record);
1750 * Contract to build a report.
1751 * @param array $meta
1752 * @param object|null $jobRecord
1753 * @param array $input
1754 * @return \Workspace\Contract\AbstractBase
1755 * @throws \Exception
1757 public function conReport($meta, $jobRecord, array $input = array())
1760 if (isset($meta['RequireAuth'])
1761 && true == $meta['RequireAuth']
1762 && !\Utility\Registry::isAuthenticated())
1764 throw new \Exception('Authentication required for this functionality.');
1766 if (isset($this->meta['JobField']) && is_null($jobRecord))
1768 throw new \Exception('`JobId` root parameter is required for this contract.');
1770 $options = $this->buildOptions($meta);
1771 $requirement = $this->buildRequirements($meta);
1772 $contract = new \Workspace\Contract\Recurring($options, $requirement);
1773 return $this->buildConditions($contract, $meta);
1778 * @param array $meta
1779 * @param object|null $jobRecord
1780 * @param \Workspace\Utility\ServiceInputParams $contract
1782 * @throws \Exception
1784 public function exeReport($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1787 if (isset($meta['RequireAuth'])
1788 && true == $meta['RequireAuth']
1789 && !\Utility\Registry::isAuthenticated())
1791 throw new \Exception('Authentication required for this functionality.');
1793 $options = $contract->options;
1794 $input = isset($contract->data->Report)
1795 ? $contract->data->Report
1797 if (isset($this->meta['JobField']))
1799 $input[$this->meta['JobField']] = $jobRecord->id;
1801 $reportService = $meta['Builder'];
1802 $report = new $reportService();
1803 $report->process($input, $options);
1804 $reportWriter = $meta['Writer'];
1807 $output = isset($meta['Output'])
1810 if ('Download' == $output)
1812 $writer = new $reportWriter($report);
1816 elseif ('File' == $output)
1818 $writer = new $reportWriter($report);
1819 $writer->output($meta['FilePath']);
1820 return $contract->success('Report saved to file.');
1822 elseif ('Raw' == $output)
1824 return $contract->success('Report Generated', array(
1825 'Title' => $report->getTitle(),
1826 'Description' => $report->getDescription(),
1827 'QueryDetails' => $report->getQueries(),
1828 'Headers' => $report->getHeaders(),
1829 'Fields' => $report->getFields(),
1830 'TotalFields' => $report->getTotalFields(),
1831 'Notes' => $report->getNotes(),
1832 'Data' => $report->getDataIntersection()
1837 $writer = new $reportWriter($report);
1838 return $contract->success('Report Generated', $writer->output());
1844 * Contract to build a report.
1845 * @param array $meta
1846 * @param object|null $jobRecord
1847 * @param array $input
1848 * @return \Workspace\Contract\AbstractBase
1849 * @throws \Exception
1851 public function conPdf($meta, $jobRecord, array $input = array())
1854 if (isset($meta['RequireAuth'])
1855 && true == $meta['RequireAuth']
1856 && !\Utility\Registry::isAuthenticated())
1858 throw new \Exception('Authentication required for this functionality.');
1860 if (isset($this->meta['JobField']) && is_null($jobRecord))
1862 throw new \Exception('`JobId` root parameter is required for this contract.');
1864 $options = $this->buildOptions($meta);
1865 $requirement = $this->buildRequirements($meta);
1866 $contract = new \Workspace\Contract\Recurring($options, $requirement);
1867 return $this->buildConditions($contract, $meta);
1872 * @param array $meta
1873 * @param object|null $jobRecord
1874 * @param \Workspace\Utility\ServiceInputParams $contract
1876 * @throws \Exception
1878 public function exePdf($meta, $jobRecord, \Workspace\Utility\ServiceInputParams $contract)
1881 if (isset($meta['RequireAuth'])
1882 && true == $meta['RequireAuth']
1883 && !\Utility\Registry::isAuthenticated())
1885 throw new \Exception('Authentication required for this functionality.');
1887 $options = $contract->options;
1888 $input = isset($contract->data->Report)
1889 ? $contract->data->Report
1891 $input['jobRecord'] = $jobRecord;
1892 $input['contract'] = $contract->data;
1893 if (isset($this->meta['JobField']))
1895 $input[$this->meta['JobField']] = $jobRecord->id;
1897 $pdfService = $meta['Builder'];
1898 $pdf = new $pdfService();
1899 $pdf->process($input, $options);
1900 $pdfWriter = $meta['Writer'];
1903 $output = isset($meta['Output'])
1906 if ('Download' == $output)
1908 $writer = new $pdfWriter($pdf);
1912 elseif ('File' == $output)
1914 $writer = new $pdfWriter($pdf);
1915 file_put_contents($meta['FilePath'], $writer->output(''));
1916 return $contract->success('PDF saved to file.');
1918 elseif ('Raw' == $output)
1920 return $contract->success('PDF Generated', array(
1921 'Title' => $pdf->getTitle(),
1922 'HTML' => $pdf->getHtml()
1927 $writer = new $pdfWriter($pdf);
1928 return $contract->success('PDF Generated', $writer->output());