From ba10636f57831b7940445ce4a30c56dff39c45a5 Mon Sep 17 00:00:00 2001
From: Jaap Jansma <jaap.jansma@civicoop.org>
Date: Fri, 3 May 2019 16:36:15 +0200
Subject: [PATCH] Added website source. Update fxied issue with status

---
 CRM/Dataprocessor/BAO/DataProcessor.php       | 33 ++++++++++++
 CRM/Dataprocessor/Form/DataProcessor.php      |  9 +++-
 CRM/Dataprocessor/Utils/Importer.php          |  5 +-
 Civi/DataProcessor/Factory.php                |  1 +
 .../Source/Contact/WebsiteSource.php          | 54 +++++++++++++++++++
 api/v3/DataProcessor.mgd.php                  | 23 ++++++++
 api/v3/DataProcessor.php                      | 20 ++++++-
 api/v3/DataProcessorField.php                 |  7 ++-
 api/v3/DataProcessorFilter.php                |  7 ++-
 api/v3/DataProcessorOutput.php                |  7 ++-
 api/v3/DataProcessorSource.php                |  7 ++-
 .../CRM/Dataprocessor/Form/DataProcessor.tpl  |  6 +--
 .../Form/DataProcessorBlocks/Fields.tpl       | 11 ++--
 .../Form/DataProcessorBlocks/Filters.tpl      | 12 ++---
 .../Form/DataProcessorBlocks/Sources.tpl      | 13 ++---
 15 files changed, 179 insertions(+), 36 deletions(-)
 create mode 100644 Civi/DataProcessor/Source/Contact/WebsiteSource.php
 create mode 100644 api/v3/DataProcessor.mgd.php

diff --git a/CRM/Dataprocessor/BAO/DataProcessor.php b/CRM/Dataprocessor/BAO/DataProcessor.php
index d06e4bd3..57060e8e 100644
--- a/CRM/Dataprocessor/BAO/DataProcessor.php
+++ b/CRM/Dataprocessor/BAO/DataProcessor.php
@@ -3,6 +3,8 @@ use CRM_Dataprocessor_ExtensionUtil as E;
 
 class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProcessor {
 
+  static $importingDataProcessors = array();
+
   public static function checkName($title, $id=null,$name=null) {
     if (!$name) {
       $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($title));
@@ -115,4 +117,35 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
     return true;
   }
 
+  /**
+   * Update the status from in code to overriden when a data processor has been changed
+   *
+   * @param $dataProcessorId
+   */
+  public static function updateAndChekStatus($dataProcessorId) {
+    $sql = "SELECT `status`, `name` FROM `civicrm_data_processor` WHERE `id` = %1";
+    $params[1] = array($dataProcessorId, 'Integer');
+    $dao = CRM_Core_DAO::executeQuery($sql, $params);
+    if ($dao->fetch()) {
+      if (!in_array($dao->name, self::$importingDataProcessors) && $dao->status == CRM_Dataprocessor_Status::STATUS_IN_CODE) {
+        $sql = "UPDATE `civicrm_data_processor` SET `status` = %2 WHERE `id` = %1";
+        $params[1] = array($dataProcessorId, 'String');
+        $params[2] = array(CRM_Dataprocessor_Status::STATUS_OVERRIDDEN, 'Integer');
+        CRM_Core_DAO::executeQuery($sql, $params);
+      }
+    }
+  }
+
+  /**
+   * Store the data processor name so we know that we are importing this data processor
+   * and should not update its status on the way.
+   *
+   * @param $dataProcessorName
+   */
+  public static function setDataProcessorToImportingState($dataProcessorName) {
+    self::$importingDataProcessors[] = $dataProcessorName;
+  }
+
+
+
 }
diff --git a/CRM/Dataprocessor/Form/DataProcessor.php b/CRM/Dataprocessor/Form/DataProcessor.php
index eaa2cf8d..21c931bd 100644
--- a/CRM/Dataprocessor/Form/DataProcessor.php
+++ b/CRM/Dataprocessor/Form/DataProcessor.php
@@ -27,22 +27,29 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
    */
   function preProcess() {
     $this->dataProcessorId = CRM_Utils_Request::retrieve('id', 'Integer');
+    if ($this->dataProcessorId) {
+      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', ['id' => $this->dataProcessorId]);
+      $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
+    }
     $this->currentUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     $this->assign('data_processor_id', $this->dataProcessorId);
 
     $session = CRM_Core_Session::singleton();
     switch($this->_action) {
       case CRM_Core_Action::DISABLE:
+        CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($this->dataProcessor['name']);
         civicrm_api3('DataProcessor', 'create', array('id' => $this->dataProcessorId, 'is_active' => 0));
         $session->setStatus('Data Processor disabled', 'Disable', 'success');
         CRM_Utils_System::redirect($session->readUserContext());
         break;
       case CRM_Core_Action::ENABLE:
+        CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($this->dataProcessor['name']);
         civicrm_api3('DataProcessor', 'create', array('id' => $this->dataProcessorId, 'is_active' => 1));
         $session->setStatus('Data Processor enabled', 'Enable', 'success');
         CRM_Utils_System::redirect($session->readUserContext());
         break;
       case CRM_Core_Action::REVERT:
+        CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($this->dataProcessor['name']);
         CRM_Dataprocessor_BAO_DataProcessor::revert($this->dataProcessorId);
         $session->setStatus('Data Processor reverted', 'Revert', 'success');
         CRM_Utils_System::redirect($session->readUserContext());
@@ -53,8 +60,6 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
     }
 
     if ($this->dataProcessorId) {
-      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId));
-      $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
       $this->assign('dataProcessor', $this->dataProcessor);
       $this->addSources();
       $this->addFields();
diff --git a/CRM/Dataprocessor/Utils/Importer.php b/CRM/Dataprocessor/Utils/Importer.php
index 1d88647f..6324b9a4 100644
--- a/CRM/Dataprocessor/Utils/Importer.php
+++ b/CRM/Dataprocessor/Utils/Importer.php
@@ -70,6 +70,8 @@ class CRM_Dataprocessor_Utils_Importer {
       // Do nothing
     }
 
+    CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($data['name']);
+
     switch ($status) {
       case CRM_Dataprocessor_Status::STATUS_IN_DATABASE:
         // Update to overriden
@@ -157,7 +159,6 @@ class CRM_Dataprocessor_Utils_Importer {
       $params = $data_source;
       $params['data_processor_id'] = $id;
       $params['debug'] = 1;
-      var_dump($params);
       try {
         civicrm_api3('DataProcessorSource', 'create', $params);
       } catch (\CiviCRM_API3_Exception $e) {
@@ -200,7 +201,7 @@ class CRM_Dataprocessor_Utils_Importer {
     }
 
     // Remove all data processors which are in code or overridden but not imported
-    $dao = CRM_Core_DAO::executeQuery("SELECT id, name FROM civicrm_data_processor WHERE id NOT IN (".implode($importedIds, ",").") AND status IN (".CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_CODE.", ".CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN.")");
+    $dao = CRM_Core_DAO::executeQuery("SELECT id, name FROM civicrm_data_processor WHERE id NOT IN (".implode($importedIds, ",").") AND status IN (".CRM_Dataprocessor_Status::STATUS_IN_CODE.", ".CRM_Dataprocessor_Status::STATUS_OVERRIDDEN.")");
     while ($dao->fetch()) {
       CRM_Dataprocessor_BAO_DataProcessor::deleteWithId($dao->id);
       $return['deleted data processors'][] = $dao->id.": ".$dao->name;
diff --git a/Civi/DataProcessor/Factory.php b/Civi/DataProcessor/Factory.php
index 823e2bc5..16f007d8 100644
--- a/Civi/DataProcessor/Factory.php
+++ b/Civi/DataProcessor/Factory.php
@@ -105,6 +105,7 @@ class Factory {
     $this->addDataSource('email', 'Civi\DataProcessor\Source\Contact\EmailSource', E::ts('E-mail'));
     $this->addDataSource('address', 'Civi\DataProcessor\Source\Contact\AddressSource', E::ts('Address'));
     $this->addDataSource('phone', 'Civi\DataProcessor\Source\Contact\PhoneSource', E::ts('Phone'));
+    $this->addDataSource('website', 'Civi\DataProcessor\Source\Contact\WebsiteSource', E::ts('Website'));
     $this->addDataSource('contribution', 'Civi\DataProcessor\Source\Contribution\ContributionSource', E::ts('Contribution'));
     $this->addDataSource('relationship', 'Civi\DataProcessor\Source\Contact\RelationshipSource', E::ts('Relationship'));
     $this->addDataSource('relationship_type', 'Civi\DataProcessor\Source\Contact\RelationshipTypeSource', E::ts('Relationship Type'));
diff --git a/Civi/DataProcessor/Source/Contact/WebsiteSource.php b/Civi/DataProcessor/Source/Contact/WebsiteSource.php
new file mode 100644
index 00000000..1122fa21
--- /dev/null
+++ b/Civi/DataProcessor/Source/Contact/WebsiteSource.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @author Jaap Jansma <jaap.jansma@civicoop.org>
+ * @license AGPL-3.0
+ */
+
+namespace Civi\DataProcessor\Source\Contact;
+
+use Civi\DataProcessor\Source\AbstractCivicrmEntitySource;
+
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class WebsiteSource extends AbstractCivicrmEntitySource {
+
+  /**
+   * Returns the entity name
+   *
+   * @return String
+   */
+  protected function getEntity() {
+    return 'Website';
+  }
+
+  /**
+   * Returns the table name of this entity
+   *
+   * @return String
+   */
+  protected function getTable() {
+    return 'civicrm_website';
+  }
+
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array(
+      'website_type_id',
+    );
+  }
+
+  /**
+   * Returns the default configuration for this data source
+   *
+   * @return array
+   */
+  public function getDefaultConfiguration() {
+    return array();
+  }
+
+}
\ No newline at end of file
diff --git a/api/v3/DataProcessor.mgd.php b/api/v3/DataProcessor.mgd.php
new file mode 100644
index 00000000..b513d682
--- /dev/null
+++ b/api/v3/DataProcessor.mgd.php
@@ -0,0 +1,23 @@
+<?php
+// This file declares a managed database record of type "Job".
+// The record will be automatically inserted, updated, or deleted from the
+// database as appropriate. For more details, see "hook_civicrm_managed" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC42/Hook+Reference
+return array (
+  0 =>
+    array (
+      'name' => 'Cron:DataProcessor.Import',
+      'entity' => 'Job',
+      'params' =>
+        array (
+          'version' => 3,
+          'name' => 'Import Data Processors',
+          'description' => 'Updates the data processor(s) from source files. Run this job manually if you want to update your changes into the database.',
+          'run_frequency' => 'Daily',
+          'api_entity' => 'DataProcessor',
+          'api_action' => 'Import',
+          'parameters' => '',
+          'is_active' => 0,
+        ),
+    ),
+);
diff --git a/api/v3/DataProcessor.php b/api/v3/DataProcessor.php
index 8e865ff2..6b219184 100644
--- a/api/v3/DataProcessor.php
+++ b/api/v3/DataProcessor.php
@@ -34,7 +34,9 @@ function civicrm_api3_data_processor_create($params) {
   if (!isset($params['id']) && !isset($params['type'])) {
     $params['type'] = 'default';
   }
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $return = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($return['id']);
+  return $return;
 }
 
 /**
@@ -140,3 +142,19 @@ function civicrm_api3_data_processor_check_name($params) {
     'name' => $name,
   );
 }
+
+/**
+ * DataProcessor.Import API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @see civicrm_api3_create_success
+ * @see civicrm_api3_create_error
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_import($params) {
+  $returnValues = array();
+  $returnValues['import'] = CRM_Dataprocessor_Utils_Importer::importFromExtensions();
+  $returnValues['is_error'] = 0;
+  return $returnValues;
+}
diff --git a/api/v3/DataProcessorField.php b/api/v3/DataProcessorField.php
index bf5161cf..72555329 100644
--- a/api/v3/DataProcessorField.php
+++ b/api/v3/DataProcessorField.php
@@ -39,7 +39,10 @@ function civicrm_api3_data_processor_field_create($params) {
     $name = $params['name'];
   }
   $params['name'] = CRM_Dataprocessor_BAO_DataProcessorField::checkName($params['title'], $params['data_processor_id'], $id, $name);
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $return = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $dataProcessorId = civicrm_api3('DataProcessorField', 'getvalue', array('id' => $return['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
+  return $return;
 }
 
 /**
@@ -50,6 +53,8 @@ function civicrm_api3_data_processor_field_create($params) {
  * @throws API_Exception
  */
 function civicrm_api3_data_processor_field_delete($params) {
+  $dataProcessorId = civicrm_api3('DataProcessorField', 'getvalue', array('id' => $params['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
diff --git a/api/v3/DataProcessorFilter.php b/api/v3/DataProcessorFilter.php
index 217626d6..65614292 100644
--- a/api/v3/DataProcessorFilter.php
+++ b/api/v3/DataProcessorFilter.php
@@ -39,7 +39,10 @@ function civicrm_api3_data_processor_filter_create($params) {
     $name = $params['name'];
   }
   $params['name'] = CRM_Dataprocessor_BAO_DataProcessorFilter::checkName($params['title'], $params['data_processor_id'], $id, $name);
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $return = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $dataProcessorId = civicrm_api3('DataProcessorFilter', 'getvalue', array('id' => $return['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
+  return $return;
 }
 
 /**
@@ -50,6 +53,8 @@ function civicrm_api3_data_processor_filter_create($params) {
  * @throws API_Exception
  */
 function civicrm_api3_data_processor_filter_delete($params) {
+  $dataProcessorId = civicrm_api3('DataProcessorFilter', 'getvalue', array('id' => $params['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
diff --git a/api/v3/DataProcessorOutput.php b/api/v3/DataProcessorOutput.php
index 79a33215..9d19e169 100644
--- a/api/v3/DataProcessorOutput.php
+++ b/api/v3/DataProcessorOutput.php
@@ -27,7 +27,10 @@ function _civicrm_api3_data_processor_output_create_spec(&$spec) {
  * @throws API_Exception
  */
 function civicrm_api3_data_processor_output_create($params) {
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $return = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $dataProcessorId = civicrm_api3('DataProcessorOutput', 'getvalue', array('id' => $return['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
+  return $return;
 }
 
 /**
@@ -38,6 +41,8 @@ function civicrm_api3_data_processor_output_create($params) {
  * @throws API_Exception
  */
 function civicrm_api3_data_processor_output_delete($params) {
+  $dataProcessorId = civicrm_api3('DataProcessorOutput', 'getvalue', array('id' => $params['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
diff --git a/api/v3/DataProcessorSource.php b/api/v3/DataProcessorSource.php
index a73f883d..946523ab 100644
--- a/api/v3/DataProcessorSource.php
+++ b/api/v3/DataProcessorSource.php
@@ -39,7 +39,10 @@ function civicrm_api3_data_processor_source_create($params) {
     $name = $params['name'];
   }
   $params['name'] = CRM_Dataprocessor_BAO_DataProcessorSource::checkName($params['title'], $params['data_processor_id'], $id, $name);
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $return = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  $dataProcessorId = civicrm_api3('DataProcessorSource', 'getvalue', array('id' => $return['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
+  return $return;
 }
 
 /**
@@ -50,6 +53,8 @@ function civicrm_api3_data_processor_source_create($params) {
  * @throws API_Exception
  */
 function civicrm_api3_data_processor_source_delete($params) {
+  $dataProcessorId = civicrm_api3('DataProcessorSource', 'getvalue', array('id' => $params['id'], 'return' => 'data_processor_id'));
+  CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessorId);
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessor.tpl b/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
index 7b4a28c2..13975c64 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
@@ -58,15 +58,15 @@
   {if $data_processor_id}
     <table>
       <tr>
-        <td>
+        <td style="width: 33%;">
           {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl"}
           {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/AggregateFields.tpl"}
           {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl"}
         </td>
-        <td>
+        <td style="width: 33%;">
           {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl"}
         </td>
-        <td>
+        <td style="width: 33%;">
           {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl"}
         </td>
       </tr>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
index c9df5257..5cc3947d 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
@@ -4,20 +4,15 @@
     <table>
         <tr>
             <th>{ts}Title{/ts}</th>
-            <th>{ts}System Name{/ts}</th>
-            <th></th>
             <th></th>
             <th></th>
         </tr>
         {foreach from=$fields item=field}
             <tr>
-                <td>{$field.title}</td>
-                <td><span class="description">{$field.name}</span></td>
-                <td>{if ($field.weight && !is_numeric($field.weight))}{$field.weight}{/if}</td>
-                <td>
+                <td>{$field.title} <br /><span class="description">{$field.name}</span></td>
+                <td style="width: 20%">{if ($field.weight && !is_numeric($field.weight))}{$field.weight}{/if}</td>
+                <td style="width: 20%">
                     <a href="{crmURL p="civicrm/dataprocessor/form/field" q="reset=1&action=update&data_processor_id=`$field.data_processor_id`&id=`$field.id`"}">{ts}Edit{/ts}</a>
-                </td>
-                <td>
                     <a href="{crmURL p="civicrm/dataprocessor/form/field" q="reset=1&action=delete&data_processor_id=`$field.data_processor_id`&id=`$field.id`"}">{ts}Remove{/ts}</a>
                 </td>
             </tr>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
index 90448919..b818ab4a 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
@@ -4,8 +4,6 @@
         <table>
             <tr>
                 <th>{ts}Title{/ts}</th>
-                <th>{ts}System name{/ts}</th>
-                <th></th>
                 <th></th>
                 <th></th>
             </tr>
@@ -15,14 +13,12 @@
                         {$filter.title}
                         {if ($filter.is_required)}
                             <span class="crm-marker">*</span>
-                        {/if}
+                        {/if} <br />
+                        <span class="description">{$filter.name}</span>
                     </td>
-                    <td><span class="description">{$filter.name}</span></td>
-                    <td>{if ($filter.weight && !is_numeric($filter.weight))}{$filter.weight}{/if}</td>
-                    <td>
+                    <td style="width: 20%">{if ($filter.weight && !is_numeric($filter.weight))}{$filter.weight}{/if}</td>
+                    <td style="width: 20%">
                         <a href="{crmURL p="civicrm/dataprocessor/form/filter" q="reset=1&action=update&data_processor_id=`$filter.data_processor_id`&id=`$filter.id`"}">{ts}Edit{/ts}</a>
-                    </td>
-                    <td>
                         <a href="{crmURL p="civicrm/dataprocessor/form/filter" q="reset=1&action=delete&data_processor_id=`$filter.data_processor_id`&id=`$filter.id`"}">{ts}Remove{/ts}</a>
                     </td>
                 </tr>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
index d2015c85..f21513a2 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
@@ -3,21 +3,18 @@
 <div class="crm-block crm-form-block crm-data-processor_source-block">
     <table>
         <tr>
-            <th>{ts}Source{/ts}</th>
             <th>{ts}Title{/ts}</th>
             <th></th>
             <th></th>
-            <th></th>
         </tr>
         {foreach from=$sources item=source}
             <tr>
-                <td>{$source.type_name}</td>
-                <td>{$source.title}</td>
-                <td>{if ($source.weight && !is_numeric($source.weight))}{$source.weight}{/if}</td>
-                <td>
-                    <a href="{crmURL p="civicrm/dataprocessor/form/source" q="reset=1&action=update&data_processor_id=`$source.data_processor_id`&id=`$source.id`"}">{ts}Edit{/ts}</a>
+                <td>{$source.title} <br />
+                    <span class="description">{$source.type_name}</span>
                 </td>
-                <td>
+                <td style="width: 20%">{if ($source.weight && !is_numeric($source.weight))}{$source.weight}{/if}</td>
+                <td style="width: 20%">
+                    <a href="{crmURL p="civicrm/dataprocessor/form/source" q="reset=1&action=update&data_processor_id=`$source.data_processor_id`&id=`$source.id`"}">{ts}Edit{/ts}</a>
                     <a href="{crmURL p="civicrm/dataprocessor/form/source" q="reset=1&action=delete&data_processor_id=`$source.data_processor_id`&id=`$source.id`"}">{ts}Remove{/ts}</a>
                 </td>
             </tr>
-- 
GitLab