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
17 * The XMLRepository is responsible for loading XML for case-types.
18 * It includes any bulk operations that apply across the list of all XML
19 * documents of all case-types.
21 class CRM_Case_XMLRepository
{
22 private static $singleton;
26 * <String,SimpleXMLElement>
33 protected $hookCache = NULL;
36 * Symbolic names of case-types.
40 protected $allCaseTypes = NULL;
44 * @return CRM_Case_XMLRepository
46 public static function singleton($fresh = FALSE) {
47 if (!self
::$singleton ||
$fresh) {
48 self
::$singleton = new static();
50 return self
::$singleton;
53 public function flush() {
55 $this->hookCache
= NULL;
56 $this->allCaseTypes
= NULL;
57 CRM_Core_DAO
::$_dbColumnValueCache = [];
63 * @param array $allCaseTypes
66 public function __construct($allCaseTypes = NULL, $xml = []) {
67 $this->allCaseTypes
= $allCaseTypes;
74 * @param string $caseType
76 * @return FALSE|\SimpleXMLElement
77 * @throws \CRM_Core_Exception
79 public function retrieve($caseType) {
80 // check if xml definition is defined in db
81 $definition = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $caseType, 'definition', 'name');
83 if (!empty($definition)) {
84 list ($xml, $error) = CRM_Utils_XML
::parseString($definition);
86 throw new CRM_Core_Exception("Failed to parse CaseType XML: $error");
91 // TODO In 4.6 or 5.0, remove support for weird machine-names
92 //if (!CRM_Case_BAO_CaseType::isValidName($caseType)) {
93 // // perhaps caller provider a the label instead of the name?
94 // throw new CRM_Core_Exception("Cannot load caseType with malformed name [$caseType]");
97 if (empty($this->xml
[$caseType])) {
98 $fileXml = $this->retrieveFile($caseType);
100 $this->xml
[$caseType] = $fileXml;
106 return $this->xml
[$caseType];
112 * @param string $caseType
113 * @return SimpleXMLElement|FALSE
115 public function retrieveFile($caseType) {
119 if (CRM_Case_BAO_CaseType
::isValidName($caseType)) {
120 // Search for a file based directly on the $caseType name
121 $fileName = $this->findXmlFile($caseType);
124 // For backward compatibility, also search for double-munged file names
125 // TODO In 4.6 or 5.0, remove support for loading double-munged file names
126 if (!$fileName ||
!file_exists($fileName)) {
127 $fileName = $this->findXmlFile(CRM_Case_XMLProcessor
::mungeCaseType($caseType));
130 if ($fileName && file_exists($fileName)) {
132 $dom = new DomDocument();
133 $xmlString = file_get_contents($fileName);
134 $dom->loadXML($xmlString);
135 $dom->documentURI
= $fileName;
137 $fileXml = simplexml_import_dom($dom);
146 * @param string $caseType
147 * @return null|string
150 public function findXmlFile($caseType) {
151 // first check custom templates directory
154 if (!$fileName ||
!file_exists($fileName)) {
155 $caseTypesViaHook = $this->getCaseTypesViaHook();
156 if (isset($caseTypesViaHook[$caseType], $caseTypesViaHook[$caseType]['file'])) {
157 $fileName = $caseTypesViaHook[$caseType]['file'];
161 if (!$fileName ||
!file_exists($fileName)) {
162 $config = CRM_Core_Config
::singleton();
163 if (isset($config->customTemplateDir
) && $config->customTemplateDir
) {
164 // check if the file exists in the custom templates directory
165 $fileName = implode(DIRECTORY_SEPARATOR
,
167 $config->customTemplateDir
,
178 if (!$fileName ||
!file_exists($fileName)) {
179 if (!file_exists($fileName)) {
180 // check if file exists locally
181 $fileName = implode(DIRECTORY_SEPARATOR
,
191 if (!file_exists($fileName)) {
192 // check if file exists locally
193 $fileName = implode(DIRECTORY_SEPARATOR
,
197 'configuration.sample',
203 return file_exists($fileName) ?
$fileName : NULL;
208 * @see CRM_Utils_Hook::caseTypes
210 public function getCaseTypesViaHook() {
211 if ($this->hookCache
=== NULL) {
212 $this->hookCache
= [];
213 CRM_Utils_Hook
::caseTypes($this->hookCache
);
215 return $this->hookCache
;
219 * @return array<string> symbolic names of case-types
221 public function getAllCaseTypes() {
222 if ($this->allCaseTypes
=== NULL) {
223 $this->allCaseTypes
= CRM_Case_PseudoConstant
::caseType("name");
225 return $this->allCaseTypes
;
229 * @return array<string> symbolic-names of activity-types
231 public function getAllDeclaredActivityTypes() {
234 $p = new CRM_Case_XMLProcessor_Process();
235 foreach ($this->getAllCaseTypes() as $caseTypeName) {
236 $caseTypeXML = $this->retrieve($caseTypeName);
237 $result = array_merge($result, $p->getDeclaredActivityTypes($caseTypeXML));
240 $result = array_unique($result);
246 * Relationships are straight from XML, described from perspective of non-client
248 * @return array<string> symbolic-names of relationship-types
250 public function getAllDeclaredRelationshipTypes() {
253 $p = new CRM_Case_XMLProcessor_Process();
254 foreach ($this->getAllCaseTypes() as $caseTypeName) {
255 $caseTypeXML = $this->retrieve($caseTypeName);
256 $result = array_merge($result, $p->getDeclaredRelationshipTypes($caseTypeXML));
259 $result = array_unique($result);
265 * Determine the number of times a particular activity-type is
266 * referenced in CiviCase XML.
268 * @param string $activityType
269 * Symbolic-name of an activity type.
272 public function getActivityReferenceCount($activityType) {
273 $p = new CRM_Case_XMLProcessor_Process();
275 foreach ($this->getAllCaseTypes() as $caseTypeName) {
276 $caseTypeXML = $this->retrieve($caseTypeName);
277 if (in_array($activityType, $p->getDeclaredActivityTypes($caseTypeXML))) {
285 * Determine the number of times a particular activity-type is
286 * referenced in CiviCase XML.
288 * @param string $relationshipTypeName
289 * Symbolic-name of a relationship-type.
292 public function getRelationshipReferenceCount($relationshipTypeName) {
293 $p = new CRM_Case_XMLProcessor_Process();
295 foreach ($this->getAllCaseTypes() as $caseTypeName) {
296 $caseTypeXML = $this->retrieve($caseTypeName);
297 if (in_array($relationshipTypeName, $p->getDeclaredRelationshipTypes($caseTypeXML))) {