Merge pull request #15102 from mlutfy/fixPriceSetLabelHtml
[civicrm-core.git] / CRM / Core / ManagedEntities.php
index 36c5a1be152e47c5189271d0a8bb14943417108c..a3883286963a35fd7e1eef88b2c2655905ab25e3 100644 (file)
@@ -7,26 +7,34 @@
  */
 class CRM_Core_ManagedEntities {
 
+  /**
+   * Get clean up options.
+   *
+   * @return array
+   */
   public static function getCleanupOptions() {
-    return array(
+    return [
       'always' => ts('Always'),
       'never' => ts('Never'),
       'unused' => ts('If Unused'),
-    );
+    ];
   }
 
   /**
-   * @var array($status => array($name => CRM_Core_Module))
+   * @var array
+   *   Array($status => array($name => CRM_Core_Module)).
    */
   protected $moduleIndex;
 
   /**
-   * @var array per hook_civicrm_managed
+   * @var array
+   *   List of all entity declarations.
+   * @see CRM_Utils_Hook::managed()
    */
   protected $declarations;
 
   /**
-   * Get an instance
+   * Get an instance.
    * @param bool $fresh
    * @return \CRM_Core_ManagedEntities
    */
@@ -47,7 +55,7 @@ class CRM_Core_ManagedEntities {
       function () {
         CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();
       },
-      array(),
+      [],
       'ManagedEntities::reconcile'
     );
   }
@@ -70,18 +78,23 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * Read the managed entity
+   * Read a managed entity using APIv3.
    *
-   * @return array|NULL API representation, or NULL if the entity does not exist
+   * @param string $moduleName
+   *   The name of the module which declared entity.
+   * @param string $name
+   *   The symbolic name of the entity.
+   * @return array|NULL
+   *   API representation, or NULL if the entity does not exist
    */
   public function get($moduleName, $name) {
     $dao = new CRM_Core_DAO_Managed();
     $dao->module = $moduleName;
     $dao->name = $name;
     if ($dao->find(TRUE)) {
-      $params = array(
+      $params = [
         'id' => $dao->entity_id,
-      );
+      ];
       $result = NULL;
       try {
         $result = civicrm_api3($dao->entity_type, 'getsingle', $params);
@@ -96,6 +109,12 @@ class CRM_Core_ManagedEntities {
     }
   }
 
+  /**
+   * Identify any enabled/disabled modules. Add new entities, update
+   * existing entities, and remove orphaned (stale) entities.
+   *
+   * @throws Exception
+   */
   public function reconcile() {
     if ($error = $this->validate($this->getDeclarations())) {
       throw new Exception($error);
@@ -105,7 +124,12 @@ class CRM_Core_ManagedEntities {
     $this->reconcileUnknownModules();
   }
 
-
+  /**
+   * For all enabled modules, add new entities, update
+   * existing entities, and remove orphaned (stale) entities.
+   *
+   * @throws Exception
+   */
   public function reconcileEnabledModules() {
     // Note: any thing currently declared is necessarily from
     // an active module -- because we got it from a hook!
@@ -126,11 +150,13 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * Create, update, and delete entities declared by an active module
+   * For one enabled module, add new entities, update existing entities,
+   * and remove orphaned (stale) entities.
    *
-   * @param \CRM_Core_Module|string $module string
+   * @param \CRM_Core_Module $module
    * @param array $todos
-   *   $name => array().
+   *   List of entities currently declared by this module.
+   *   array(string $name => array $entityDef).
    */
   public function reconcileEnabledModule(CRM_Core_Module $module, $todos) {
     $dao = new CRM_Core_DAO_Managed();
@@ -154,6 +180,9 @@ class CRM_Core_ManagedEntities {
     }
   }
 
+  /**
+   * For all disabled modules, disable any managed entities.
+   */
   public function reconcileDisabledModules() {
     if (empty($this->moduleIndex[FALSE])) {
       return;
@@ -162,6 +191,7 @@ class CRM_Core_ManagedEntities {
     $in = CRM_Core_DAO::escapeStrings(array_keys($this->moduleIndex[FALSE]));
     $dao = new CRM_Core_DAO_Managed();
     $dao->whereAdd("module in ($in)");
+    $dao->orderBy('id DESC');
     $dao->find();
     while ($dao->fetch()) {
       $this->disableEntity($dao);
@@ -169,20 +199,24 @@ class CRM_Core_ManagedEntities {
     }
   }
 
+  /**
+   * Remove any orphaned (stale) entities that are linked to
+   * unknown modules.
+   */
   public function reconcileUnknownModules() {
-    $knownModules = array();
+    $knownModules = [];
     if (array_key_exists(0, $this->moduleIndex) && is_array($this->moduleIndex[0])) {
       $knownModules = array_merge($knownModules, array_keys($this->moduleIndex[0]));
     }
     if (array_key_exists(1, $this->moduleIndex) && is_array($this->moduleIndex[1])) {
       $knownModules = array_merge($knownModules, array_keys($this->moduleIndex[1]));
-
     }
 
     $dao = new CRM_Core_DAO_Managed();
     if (!empty($knownModules)) {
       $in = CRM_Core_DAO::escapeStrings($knownModules);
       $dao->whereAdd("module NOT IN ($in)");
+      $dao->orderBy('id DESC');
     }
     $dao->find();
     while ($dao->fetch()) {
@@ -191,7 +225,7 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * Create a new entity
+   * Create a new entity.
    *
    * @param array $todo
    *   Entity specification (per hook_civicrm_managedEntities).
@@ -223,14 +257,15 @@ class CRM_Core_ManagedEntities {
     $doUpdate = ($policy == 'always');
 
     if ($doUpdate) {
-      $defaults = array(
+      $defaults = [
         'id' => $dao->entity_id,
-        'is_active' => 1, // FIXME: test whether is_active is valid
-      );
+      // FIXME: test whether is_active is valid
+        'is_active' => 1,
+      ];
       $params = array_merge($defaults, $todo['params']);
       $result = civicrm_api($dao->entity_type, 'create', $params);
       if ($result['is_error']) {
-        $this->onApiError($dao->entity_type, 'create',$params, $result);
+        $this->onApiError($dao->entity_type, 'create', $params, $result);
       }
     }
 
@@ -250,22 +285,23 @@ class CRM_Core_ManagedEntities {
     // FIXME: if ($dao->entity_type supports is_active) {
     if (TRUE) {
       // FIXME cascading for payproc types?
-      $params = array(
+      $params = [
         'version' => 3,
         'id' => $dao->entity_id,
         'is_active' => 0,
-      );
+      ];
       $result = civicrm_api($dao->entity_type, 'create', $params);
       if ($result['is_error']) {
-        $this->onApiError($dao->entity_type, 'create',$params, $result);
+        $this->onApiError($dao->entity_type, 'create', $params, $result);
       }
     }
   }
 
   /**
-   * Remove a stale entity (if policy allows)
+   * Remove a stale entity (if policy allows).
    *
    * @param CRM_Core_DAO_Managed $dao
+   * @throws Exception
    */
   public function removeStaleEntity($dao) {
     $policy = empty($dao->cleanup) ? 'always' : $dao->cleanup;
@@ -279,10 +315,10 @@ class CRM_Core_ManagedEntities {
         break;
 
       case 'unused':
-        $getRefCount = civicrm_api3($dao->entity_type, 'getrefcount', array(
+        $getRefCount = civicrm_api3($dao->entity_type, 'getrefcount', [
           'debug' => 1,
           'id' => $dao->entity_id,
-        ));
+        ]);
 
         $total = 0;
         foreach ($getRefCount['values'] as $refCount) {
@@ -297,24 +333,31 @@ class CRM_Core_ManagedEntities {
     }
 
     if ($doDelete) {
-      $params = array(
+      $params = [
         'version' => 3,
         'id' => $dao->entity_id,
-      );
-      $result = civicrm_api($dao->entity_type, 'delete', $params);
-      if ($result['is_error']) {
-        $this->onApiError($dao->entity_type, 'delete', $params, $result);
+      ];
+      $check = civicrm_api3($dao->entity_type, 'get', $params);
+      if ((bool) $check['count']) {
+        $result = civicrm_api($dao->entity_type, 'delete', $params);
+        if ($result['is_error']) {
+          $this->onApiError($dao->entity_type, 'delete', $params, $result);
+        }
       }
-
-      CRM_Core_DAO::executeQuery('DELETE FROM civicrm_managed WHERE id = %1', array(
-        1 => array($dao->id, 'Integer'),
-      ));
+      CRM_Core_DAO::executeQuery('DELETE FROM civicrm_managed WHERE id = %1', [
+        1 => [$dao->id, 'Integer'],
+      ]);
     }
   }
 
+  /**
+   * Get declarations.
+   *
+   * @return array|null
+   */
   public function getDeclarations() {
     if ($this->declarations === NULL) {
-      $this->declarations = array();
+      $this->declarations = [];
       foreach (CRM_Core_Component::getEnabledComponents() as $component) {
         /** @var CRM_Core_Component_Info $component */
         $this->declarations = array_merge($this->declarations, $component->getManagedEntities());
@@ -326,13 +369,14 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * @param $modules
+   * @param array $modules
+   *   Array<CRM_Core_Module>.
    *
    * @return array
    *   indexed by is_active,name
    */
   protected static function createModuleIndex($modules) {
-    $result = array();
+    $result = [];
     foreach ($modules as $module) {
       $result[$module->is_active][$module->name] = $module;
     }
@@ -340,21 +384,21 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * @param $moduleIndex
-   * @param $declarations
+   * @param array $moduleIndex
+   * @param array $declarations
    *
    * @return array
    *   indexed by module,name
    */
   protected static function createDeclarationIndex($moduleIndex, $declarations) {
-    $result = array();
+    $result = [];
     if (!isset($moduleIndex[TRUE])) {
       return $result;
     }
     foreach ($moduleIndex[TRUE] as $moduleName => $module) {
       if ($module->is_active) {
         // need an empty array() for all active modules, even if there are no current $declarations
-        $result[$moduleName] = array();
+        $result[$moduleName] = [];
       }
     }
     foreach ($declarations as $declaration) {
@@ -366,11 +410,12 @@ class CRM_Core_ManagedEntities {
   /**
    * @param $declarations
    *
-   * @return mixed string on error, or FALSE
+   * @return string|bool
+   *   string on error, or FALSE
    */
   protected static function validate($declarations) {
     foreach ($declarations as $declare) {
-      foreach (array('name', 'module', 'entity', 'params') as $key) {
+      foreach (['name', 'module', 'entity', 'params'] as $key) {
         if (empty($declare[$key])) {
           $str = print_r($declare, TRUE);
           return ("Managed Entity is missing field \"$key\": $str");
@@ -382,9 +427,9 @@ class CRM_Core_ManagedEntities {
   }
 
   /**
-   * @param $declarations
+   * @param array $declarations
    *
-   * @return mixed
+   * @return array
    */
   protected static function cleanDeclarations($declarations) {
     foreach ($declarations as $name => &$declare) {
@@ -404,12 +449,13 @@ class CRM_Core_ManagedEntities {
    * @throws Exception
    */
   protected function onApiError($entity, $action, $params, $result) {
-    CRM_Core_Error::debug_var('ManagedEntities_failed', array(
+    CRM_Core_Error::debug_var('ManagedEntities_failed', [
       'entity' => $entity,
       'action' => $action,
       'params' => $params,
       'result' => $result,
-    ));
+    ]);
     throw new Exception('API error: ' . $result['error_message']);
   }
+
 }