316 lines
9.1 KiB
PHP
316 lines
9.1 KiB
PHP
|
<?php
|
||
|
/*
|
||
|
+--------------------------------------------------------------------+
|
||
|
| CiviCRM version 4.7 |
|
||
|
+--------------------------------------------------------------------+
|
||
|
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||
|
+--------------------------------------------------------------------+
|
||
|
| This file is a part of CiviCRM. |
|
||
|
| |
|
||
|
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||
|
| under the terms of the GNU Affero General Public License |
|
||
|
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||
|
| |
|
||
|
| CiviCRM is distributed in the hope that it will be useful, but |
|
||
|
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||
|
| See the GNU Affero General Public License for more details. |
|
||
|
| |
|
||
|
| You should have received a copy of the GNU Affero General Public |
|
||
|
| License and the CiviCRM Licensing Exception along |
|
||
|
| with this program; if not, contact CiviCRM LLC |
|
||
|
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||
|
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||
|
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||
|
+--------------------------------------------------------------------+
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @package CRM
|
||
|
* @copyright CiviCRM LLC (c) 2004-2017
|
||
|
*
|
||
|
* The XMLRepository is responsible for loading XML for case-types.
|
||
|
* It includes any bulk operations that apply across the list of all XML
|
||
|
* documents of all case-types.
|
||
|
*/
|
||
|
class CRM_Case_XMLRepository {
|
||
|
private static $singleton;
|
||
|
|
||
|
/**
|
||
|
* @var array<String,SimpleXMLElement>
|
||
|
*/
|
||
|
protected $xml = array();
|
||
|
|
||
|
/**
|
||
|
* @var array|NULL
|
||
|
*/
|
||
|
protected $hookCache = NULL;
|
||
|
|
||
|
/**
|
||
|
* @var array|NULL symbolic names of case-types
|
||
|
*/
|
||
|
protected $allCaseTypes = NULL;
|
||
|
|
||
|
/**
|
||
|
* @param bool $fresh
|
||
|
* @return CRM_Case_XMLRepository
|
||
|
*/
|
||
|
public static function singleton($fresh = FALSE) {
|
||
|
if (!self::$singleton || $fresh) {
|
||
|
self::$singleton = new static();
|
||
|
}
|
||
|
return self::$singleton;
|
||
|
}
|
||
|
|
||
|
public function flush() {
|
||
|
$this->xml = array();
|
||
|
$this->hookCache = NULL;
|
||
|
$this->allCaseTypes = NULL;
|
||
|
CRM_Core_DAO::$_dbColumnValueCache = array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Class constructor.
|
||
|
*
|
||
|
* @param array $allCaseTypes
|
||
|
* @param array $xml
|
||
|
*/
|
||
|
public function __construct($allCaseTypes = NULL, $xml = array()) {
|
||
|
$this->allCaseTypes = $allCaseTypes;
|
||
|
$this->xml = $xml;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve case.
|
||
|
*
|
||
|
* @param string $caseType
|
||
|
*
|
||
|
* @return FALSE|\SimpleXMLElement
|
||
|
* @throws \CRM_Core_Exception
|
||
|
*/
|
||
|
public function retrieve($caseType) {
|
||
|
// check if xml definition is defined in db
|
||
|
$definition = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_CaseType', $caseType, 'definition', 'name');
|
||
|
|
||
|
if (!empty($definition)) {
|
||
|
list ($xml, $error) = CRM_Utils_XML::parseString($definition);
|
||
|
if (!$xml) {
|
||
|
throw new CRM_Core_Exception("Failed to parse CaseType XML: $error");
|
||
|
}
|
||
|
return $xml;
|
||
|
}
|
||
|
|
||
|
// TODO In 4.6 or 5.0, remove support for weird machine-names
|
||
|
//if (!CRM_Case_BAO_CaseType::isValidName($caseType)) {
|
||
|
// // perhaps caller provider a the label instead of the name?
|
||
|
// throw new CRM_Core_Exception("Cannot load caseType with malformed name [$caseType]");
|
||
|
//}
|
||
|
|
||
|
if (!CRM_Utils_Array::value($caseType, $this->xml)) {
|
||
|
$fileXml = $this->retrieveFile($caseType);
|
||
|
if ($fileXml) {
|
||
|
$this->xml[$caseType] = $fileXml;
|
||
|
}
|
||
|
else {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return $this->xml[$caseType];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve file.
|
||
|
*
|
||
|
* @param string $caseType
|
||
|
* @return SimpleXMLElement|FALSE
|
||
|
*/
|
||
|
public function retrieveFile($caseType) {
|
||
|
$fileName = NULL;
|
||
|
$fileXml = NULL;
|
||
|
|
||
|
if (CRM_Case_BAO_CaseType::isValidName($caseType)) {
|
||
|
// Search for a file based directly on the $caseType name
|
||
|
$fileName = $this->findXmlFile($caseType);
|
||
|
}
|
||
|
|
||
|
// For backward compatibility, also search for double-munged file names
|
||
|
// TODO In 4.6 or 5.0, remove support for loading double-munged file names
|
||
|
if (!$fileName || !file_exists($fileName)) {
|
||
|
$fileName = $this->findXmlFile(CRM_Case_XMLProcessor::mungeCaseType($caseType));
|
||
|
}
|
||
|
|
||
|
if ($fileName && file_exists($fileName)) {
|
||
|
// read xml file
|
||
|
$dom = new DomDocument();
|
||
|
$xmlString = file_get_contents($fileName);
|
||
|
$dom->loadXML($xmlString);
|
||
|
$dom->documentURI = $fileName;
|
||
|
$dom->xinclude();
|
||
|
$fileXml = simplexml_import_dom($dom);
|
||
|
}
|
||
|
|
||
|
return $fileXml;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find xml file.
|
||
|
*
|
||
|
* @param string $caseType
|
||
|
* @return null|string
|
||
|
* file path
|
||
|
*/
|
||
|
public function findXmlFile($caseType) {
|
||
|
// first check custom templates directory
|
||
|
$fileName = NULL;
|
||
|
|
||
|
if (!$fileName || !file_exists($fileName)) {
|
||
|
$caseTypesViaHook = $this->getCaseTypesViaHook();
|
||
|
if (isset($caseTypesViaHook[$caseType], $caseTypesViaHook[$caseType]['file'])) {
|
||
|
$fileName = $caseTypesViaHook[$caseType]['file'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!$fileName || !file_exists($fileName)) {
|
||
|
$config = CRM_Core_Config::singleton();
|
||
|
if (isset($config->customTemplateDir) && $config->customTemplateDir) {
|
||
|
// check if the file exists in the custom templates directory
|
||
|
$fileName = implode(DIRECTORY_SEPARATOR,
|
||
|
array(
|
||
|
$config->customTemplateDir,
|
||
|
'CRM',
|
||
|
'Case',
|
||
|
'xml',
|
||
|
'configuration',
|
||
|
"$caseType.xml",
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!$fileName || !file_exists($fileName)) {
|
||
|
if (!file_exists($fileName)) {
|
||
|
// check if file exists locally
|
||
|
$fileName = implode(DIRECTORY_SEPARATOR,
|
||
|
array(
|
||
|
dirname(__FILE__),
|
||
|
'xml',
|
||
|
'configuration',
|
||
|
"$caseType.xml",
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (!file_exists($fileName)) {
|
||
|
// check if file exists locally
|
||
|
$fileName = implode(DIRECTORY_SEPARATOR,
|
||
|
array(
|
||
|
dirname(__FILE__),
|
||
|
'xml',
|
||
|
'configuration.sample',
|
||
|
"$caseType.xml",
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
return file_exists($fileName) ? $fileName : NULL;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
* @see CRM_Utils_Hook::caseTypes
|
||
|
*/
|
||
|
public function getCaseTypesViaHook() {
|
||
|
if ($this->hookCache === NULL) {
|
||
|
$this->hookCache = array();
|
||
|
CRM_Utils_Hook::caseTypes($this->hookCache);
|
||
|
}
|
||
|
return $this->hookCache;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array<string> symbolic names of case-types
|
||
|
*/
|
||
|
public function getAllCaseTypes() {
|
||
|
if ($this->allCaseTypes === NULL) {
|
||
|
$this->allCaseTypes = CRM_Case_PseudoConstant::caseType("name");
|
||
|
}
|
||
|
return $this->allCaseTypes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array<string> symbolic-names of activity-types
|
||
|
*/
|
||
|
public function getAllDeclaredActivityTypes() {
|
||
|
$result = array();
|
||
|
|
||
|
$p = new CRM_Case_XMLProcessor_Process();
|
||
|
foreach ($this->getAllCaseTypes() as $caseTypeName) {
|
||
|
$caseTypeXML = $this->retrieve($caseTypeName);
|
||
|
$result = array_merge($result, $p->getDeclaredActivityTypes($caseTypeXML));
|
||
|
}
|
||
|
|
||
|
$result = array_unique($result);
|
||
|
sort($result);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array<string> symbolic-names of relationship-types
|
||
|
*/
|
||
|
public function getAllDeclaredRelationshipTypes() {
|
||
|
$result = array();
|
||
|
|
||
|
$p = new CRM_Case_XMLProcessor_Process();
|
||
|
foreach ($this->getAllCaseTypes() as $caseTypeName) {
|
||
|
$caseTypeXML = $this->retrieve($caseTypeName);
|
||
|
$result = array_merge($result, $p->getDeclaredRelationshipTypes($caseTypeXML));
|
||
|
}
|
||
|
|
||
|
$result = array_unique($result);
|
||
|
sort($result);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determine the number of times a particular activity-type is
|
||
|
* referenced in CiviCase XML.
|
||
|
*
|
||
|
* @param string $activityType
|
||
|
* Symbolic-name of an activity type.
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getActivityReferenceCount($activityType) {
|
||
|
$p = new CRM_Case_XMLProcessor_Process();
|
||
|
$count = 0;
|
||
|
foreach ($this->getAllCaseTypes() as $caseTypeName) {
|
||
|
$caseTypeXML = $this->retrieve($caseTypeName);
|
||
|
if (in_array($activityType, $p->getDeclaredActivityTypes($caseTypeXML))) {
|
||
|
$count++;
|
||
|
}
|
||
|
}
|
||
|
return $count;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determine the number of times a particular activity-type is
|
||
|
* referenced in CiviCase XML.
|
||
|
*
|
||
|
* @param string $relationshipTypeName
|
||
|
* Symbolic-name of a relationship-type.
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getRelationshipReferenceCount($relationshipTypeName) {
|
||
|
$p = new CRM_Case_XMLProcessor_Process();
|
||
|
$count = 0;
|
||
|
foreach ($this->getAllCaseTypes() as $caseTypeName) {
|
||
|
$caseTypeXML = $this->retrieve($caseTypeName);
|
||
|
if (in_array($relationshipTypeName, $p->getDeclaredRelationshipTypes($caseTypeXML))) {
|
||
|
$count++;
|
||
|
}
|
||
|
}
|
||
|
return $count;
|
||
|
}
|
||
|
|
||
|
}
|