3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 * The XMLRepository is responsible for loading XML for case-types.
17 * It includes any bulk operations that apply across the list of all XML
18 * documents of all case-types.
20 class CRM_Case_XMLRepository
{
21 private static $singleton;
25 * <String,SimpleXMLElement>
32 protected $hookCache = NULL;
35 * Symbolic names of case-types.
39 protected $allCaseTypes = NULL;
43 * @return CRM_Case_XMLRepository
45 public static function singleton($fresh = FALSE) {
46 if (!self
::$singleton ||
$fresh) {
47 self
::$singleton = new static();
49 return self
::$singleton;
52 public function flush() {
54 $this->hookCache
= NULL;
55 $this->allCaseTypes
= NULL;
56 CRM_Core_DAO
::$_dbColumnValueCache = [];
62 * @param array $allCaseTypes
65 public function __construct($allCaseTypes = NULL, $xml = []) {
66 $this->allCaseTypes
= $allCaseTypes;
73 * @param string $caseType
75 * @return FALSE|\SimpleXMLElement
76 * @throws \CRM_Core_Exception
78 public function retrieve($caseType) {
79 // check if xml definition is defined in db
80 $definition = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $caseType, 'definition', 'name');
82 if (!empty($definition)) {
83 list ($xml, $error) = CRM_Utils_XML
::parseString($definition);
85 throw new CRM_Core_Exception("Failed to parse CaseType XML: $error");
90 // TODO In 4.6 or 5.0, remove support for weird machine-names
91 //if (!CRM_Case_BAO_CaseType::isValidName($caseType)) {
92 // // perhaps caller provider a the label instead of the name?
93 // throw new CRM_Core_Exception("Cannot load caseType with malformed name [$caseType]");
96 if (empty($this->xml
[$caseType])) {
97 $fileXml = $this->retrieveFile($caseType);
99 $this->xml
[$caseType] = $fileXml;
105 return $this->xml
[$caseType];
111 * @param string $caseType
112 * @return SimpleXMLElement|FALSE
114 public function retrieveFile($caseType) {
118 if (CRM_Case_BAO_CaseType
::isValidName($caseType)) {
119 // Search for a file based directly on the $caseType name
120 $fileName = $this->findXmlFile($caseType);
123 // For backward compatibility, also search for double-munged file names
124 // TODO In 4.6 or 5.0, remove support for loading double-munged file names
125 if (!$fileName ||
!file_exists($fileName)) {
126 $fileName = $this->findXmlFile(CRM_Case_XMLProcessor
::mungeCaseType($caseType));
129 if ($fileName && file_exists($fileName)) {
131 $dom = new DomDocument();
132 $xmlString = file_get_contents($fileName);
133 $dom->loadXML($xmlString);
134 $dom->documentURI
= $fileName;
136 $fileXml = simplexml_import_dom($dom);
145 * @param string $caseType
146 * @return null|string
149 public function findXmlFile($caseType) {
150 // first check custom templates directory
153 if (!$fileName ||
!file_exists($fileName)) {
154 $caseTypesViaHook = $this->getCaseTypesViaHook();
155 if (isset($caseTypesViaHook[$caseType], $caseTypesViaHook[$caseType]['file'])) {
156 $fileName = $caseTypesViaHook[$caseType]['file'];
160 if (!$fileName ||
!file_exists($fileName)) {
161 $config = CRM_Core_Config
::singleton();
162 if (isset($config->customTemplateDir
) && $config->customTemplateDir
) {
163 // check if the file exists in the custom templates directory
164 $fileName = implode(DIRECTORY_SEPARATOR
,
166 $config->customTemplateDir
,
177 if (!$fileName ||
!file_exists($fileName)) {
178 if (!file_exists($fileName)) {
179 // check if file exists locally
180 $fileName = implode(DIRECTORY_SEPARATOR
,
190 if (!file_exists($fileName)) {
191 // check if file exists locally
192 $fileName = implode(DIRECTORY_SEPARATOR
,
196 'configuration.sample',
202 return file_exists($fileName) ?
$fileName : NULL;
207 * @see CRM_Utils_Hook::caseTypes
209 public function getCaseTypesViaHook() {
210 if ($this->hookCache
=== NULL) {
211 $this->hookCache
= [];
212 CRM_Utils_Hook
::caseTypes($this->hookCache
);
214 return $this->hookCache
;
218 * @return array<string> symbolic names of case-types
220 public function getAllCaseTypes() {
221 if ($this->allCaseTypes
=== NULL) {
222 $this->allCaseTypes
= CRM_Case_PseudoConstant
::caseType("name");
224 return $this->allCaseTypes
;
228 * @return array<string> symbolic-names of activity-types
230 public function getAllDeclaredActivityTypes() {
233 $p = new CRM_Case_XMLProcessor_Process();
234 foreach ($this->getAllCaseTypes() as $caseTypeName) {
235 $caseTypeXML = $this->retrieve($caseTypeName);
236 $result = array_merge($result, $p->getDeclaredActivityTypes($caseTypeXML));
239 $result = array_unique($result);
245 * Relationships are straight from XML, described from perspective of non-client
247 * @return array<string> symbolic-names of relationship-types
249 public function getAllDeclaredRelationshipTypes() {
252 $p = new CRM_Case_XMLProcessor_Process();
253 foreach ($this->getAllCaseTypes() as $caseTypeName) {
254 $caseTypeXML = $this->retrieve($caseTypeName);
255 $result = array_merge($result, $p->getDeclaredRelationshipTypes($caseTypeXML));
258 $result = array_unique($result);
264 * Determine the number of times a particular activity-type is
265 * referenced in CiviCase XML.
267 * @param string $activityType
268 * Symbolic-name of an activity type.
271 public function getActivityReferenceCount($activityType) {
272 $p = new CRM_Case_XMLProcessor_Process();
274 foreach ($this->getAllCaseTypes() as $caseTypeName) {
275 $caseTypeXML = $this->retrieve($caseTypeName);
276 if (in_array($activityType, $p->getDeclaredActivityTypes($caseTypeXML))) {
284 * Determine the number of times a particular activity-type is
285 * referenced in CiviCase XML.
287 * @param string $relationshipTypeName
288 * Symbolic-name of a relationship-type.
291 public function getRelationshipReferenceCount($relationshipTypeName) {
292 $p = new CRM_Case_XMLProcessor_Process();
294 foreach ($this->getAllCaseTypes() as $caseTypeName) {
295 $caseTypeXML = $this->retrieve($caseTypeName);
296 if (in_array($relationshipTypeName, $p->getDeclaredRelationshipTypes($caseTypeXML))) {