Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) CRM-18323- PCP Search implementation like group search #8045

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CRM/Admin/Page/AJAX.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ public static function getStatusMsg() {
$ret['content'] .= '<br /><br /><strong>' . ts('This recurring contribution is linked to an auto-renew membership. If you cancel it, the associated membership will no longer renew automatically. However, the current membership status will not be affected.') . '</strong>';
}
break;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style issues? This is super indented =]

case 'CRM_PCP_BAO_PCP':
$ret['content'] = ts('Are you sure you want to disable this Personal Campaign Page?');
break;

default:
$ret['content'] = ts('Are you sure you want to disable this record?');
Expand Down
13 changes: 10 additions & 3 deletions CRM/Core/xml/Menu/PCP.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
<menu>
<item>
<path>civicrm/pcp</path>
<page_callback>CRM_PCP_Form_PCP</page_callback>
<access_callback>1</access_callback>
<is_public>true</is_public>
<title>Manage Personal Campaign Pages</title>
<page_type>1</page_type>
<page_callback>CRM_PCP_Page_PCP</page_callback>
<access_arguments>access CiviCRM</access_arguments>
<weight>30</weight>
</item>
<item>
<path>civicrm/pcp/campaign</path>
Expand All @@ -26,4 +28,9 @@
<page_callback>CRM_PCP_Page_PCP</page_callback>
<desc>View and manage existing personal campaign pages.</desc>
</item>
<item>
<path>civicrm/ajax/pcplist</path>
<page_callback>CRM_PCP_Page_AJAX::getPcpList</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
</menu>
281 changes: 281 additions & 0 deletions CRM/PCP/BAO/PCP.php
Original file line number Diff line number Diff line change
Expand Up @@ -931,5 +931,286 @@ public static function getOwnerNotificationId($component_id, $component = 'contr
return $ownerNotificationId;
}
}

/**
* wrapper for ajax pcp selector.
*
* @param array $params
* Associated array for params record id.
*
* @return array
* associated array of pcp list
* -rp = rowcount
* -page= offset
* @todo there seems little reason for the small number of functions that call this to pass in
* params that then need to be translated in this function since they are coding them when calling
*/
static public function getPcpListSelector(&$params) {
// format the params
$params['offset'] = ($params['page'] - 1) * $params['rp'];
$params['rowCount'] = $params['rp'];
$params['sort'] = CRM_Utils_Array::value('sortBy', $params);

// get pcps
$pcps = CRM_PCP_BAO_PCP::getPcpList($params);
$params['total'] = CRM_PCP_BAO_PCP::getPcpCount($params);

// format params and add links
$pcpList = array();
if (!empty($pcps)) {
foreach ($pcps as $id => $value) {
$value['class'][] = 'crm-entity';
$pcpList[$id]['class'] = $value['id'] . ',' . implode(' ', $value['class']);
$pcpList[$id]['pcp_id'] = $value['id'];
$pcpList[$id]['pcp_name'] = $value['pcp_title'];
$value['class'][] = 'crm-entity';
$pcpList[$id]['class'] = $value['id'] . ',' . implode(' ', $value['class']);
$pcpList[$id]['pcp_supporter'] = CRM_Utils_Array::value('pcp_supporter', $value);
$pcpList[$id]['pcp_page'] = CRM_Utils_Array::value('pcp_page', $value);
$pcpList[$id]['pcp_start_date'] = CRM_Utils_Array::value('pcp_start_date', $value);
$pcpList[$id]['pcp_end_date'] = CRM_Utils_Array::value('pcp_end_date', $value) ? $value['pcp_end_date'] : '(ongoing)';
$pcpList[$id]['pcp_status'] = CRM_Utils_Array::value('pcp_status', $value);
$pcpList[$id]['action'] = CRM_Utils_Array::value('action', $value);
}
return $pcpList;
}
}

/**
* This function to get list of pcps.
*
* @param array $params
* Associated array for params.
*
* @return array
*/
public static function getPcpList(&$params) {
$config = CRM_Core_Config::singleton();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should go. It's not used. The codebase does seem to be littered with instantiation of the Config object so there may have been a historical reason but there should not be one now


$whereClause = self::whereClause($params, FALSE);

//$this->pagerAToZ( $whereClause, $params );

if (!empty($params['rowCount']) &&
$params['rowCount'] > 0
) {
$limit = " LIMIT {$params['offset']}, {$params['rowCount']} ";
}

$orderBy = ' ORDER BY pcps.title asc';
if (!empty($params['sort'])) {
$orderBy = ' ORDER BY ' . CRM_Utils_Type::escape($params['sort'], 'String');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is now a special escaping function on the CRM_Utils_Type class for use with ORDER BY

}

$query = "
SELECT pcps.*, pcp_supporter.display_name,
CASE WHEN pcp_block.entity_table = 'civicrm_event' THEN event.title
WHEN pcp_block.entity_table = 'civicrm_contribution_page' THEN contribution_page.title
END as page,
CASE WHEN pcp_block.entity_table = 'civicrm_event' THEN event.registration_start_date
WHEN pcp_block.entity_table = 'civicrm_contribution_page' THEN contribution_page.start_date
END as start_date,
CASE WHEN pcp_block.entity_table = 'civicrm_event' THEN event.registration_end_date
WHEN pcp_block.entity_table = 'civicrm_contribution_page' THEN contribution_page.end_date
END as end_date
FROM civicrm_pcp pcps
LEFT JOIN civicrm_contact pcp_supporter ON pcp_supporter.id = pcps.contact_id
LEFT JOIN civicrm_pcp_block pcp_block ON (pcp_block.id = pcps.pcp_block_id)
LEFT JOIN civicrm_event event ON (event.id = pcp_block.entity_id AND pcp_block.entity_table = 'civicrm_event')
LEFT JOIN civicrm_contribution_page contribution_page ON (contribution_page.id = pcp_block.entity_id AND pcp_block.entity_table = 'civicrm_contribution_page')
LEFT JOIN civicrm_email supporter_email ON (pcp_supporter.id = supporter_email.contact_id AND supporter_email.is_primary = 1)
WHERE $whereClause
GROUP BY pcps.id
{$orderBy}
{$limit}";

$object = CRM_Core_DAO::executeQuery($query, $params, TRUE, 'CRM_PCP_DAO_PCP');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any benefit to passing more than just query in? $params does not have anything relevant and I have misgivings passing it in when it is an unrelated array. It seems to me to add confusion. I don't think passing in the DAO name adds any benefit


while ($object->fetch()) {
$links = self::actionLinks();

$approvedId = CRM_Core_OptionGroup::getValue('pcp_status', 'Approved', 'name');
$allowToDelete = CRM_Core_Permission::check('delete in CiviContribute');

CRM_Core_DAO::storeValues($object, $values[$object->id]);

if ($object->page_type == 'contribute') {
$pageUrl = CRM_Utils_System::url('civicrm/' . $object->page_type . '/transact', 'reset=1&id=' . $object->page_id);
}
else {
$pageUrl = CRM_Utils_System::url('civicrm/' . $object->page_type . '/register', 'reset=1&id=' . $object->page_id);
}
$supporterUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$object->contact_id}");
$pcpUrl = CRM_Utils_System::url('civicrm/pcp/info', "reset=1&id={$object->id}");
$status = CRM_PCP_BAO_PCP::buildOptions('status_id', 'create');
$values[$object->id]['pcp_title'] = "<a href='{$pcpUrl}'>{$object->title}</a>";
$values[$object->id]['pcp_supporter'] = "<a href='{$supporterUrl}'>{$object->display_name}</a>";
$values[$object->id]['pcp_page'] = "<a href='{$pageUrl}'>{$object->page}</a>";
$values[$object->id]['pcp_start_date'] = CRM_Utils_Date::customFormat($object->start_date);
$values[$object->id]['pcp_end_date'] = CRM_Utils_Date::customFormat($object->end_date);
$values[$object->id]['pcp_status'] = $status[$object->status_id];

$action = array_sum(array_keys($links));

$class = '';

if ($object->status_id != $approvedId || $object->is_active != 1) {
$class = 'disabled';
}

switch ($object->status_id) {
case 2:
$action -= CRM_Core_Action::RENEW;
break;

case 3:
$action -= CRM_Core_Action::REVERT;
break;
}

switch ($object->is_active) {
case 1:
$action -= CRM_Core_Action::ENABLE;
break;

case 0:
$values[$object->id]['class'][] = 'disabled';
$action -= CRM_Core_Action::DISABLE;
break;
}

if (!$allowToDelete) {
$action -= CRM_Core_Action::DELETE;
}

$values[$object->id]['action'] = CRM_Core_Action::formLink($links,
$action,
array('id' => $object->id), ts('more'), FALSE, 'pcp.selector.row', 'PCP', $object->id
);

}
return $values;
}

/**
* @param array $params
*
* @return NULL|string
*/
public static function getPcpCount(&$params) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have loads of this passing as reference in the code base- but it makes for fragile code because the $params array gets altered unintentionally & then downstream someone hangs functionality off that change that breaks when someone does a tidy up.

$whereClause = self::whereClause($params, FALSE);
$query = "SELECT
COUNT(pcps.id) FROM civicrm_pcp pcps
INNER JOIN civicrm_contact pcp_supporter ON pcps.contact_id = pcp_supporter.id
LEFT JOIN civicrm_pcp_block pcp_block ON (pcp_block.id = pcps.pcp_block_id)
LEFT JOIN civicrm_event event ON (event.id = pcp_block.entity_id AND pcp_block.entity_table = 'civicrm_event')
LEFT JOIN civicrm_contribution_page contribution_page ON (contribution_page.id = pcp_block.entity_id AND pcp_block.entity_table = 'civicrm_contribution_page')
LEFT JOIN civicrm_email supporter_email ON (pcp_supporter.id = supporter_email.contact_id AND supporter_email.is_primary = 1)";
$query .= "
WHERE {$whereClause}";
return CRM_Core_DAO::singleValueQuery($query, $params);
}

/**
* Generate permissioned where clause for group search.
* @param array $params
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think style will insist on a blank line between these 2

* @param bool $sortBy
* @param bool $excludeHidden
*
* @return string
*/
public static function whereClause(&$params, $sortBy = TRUE, $excludeHidden = TRUE) {
$values = array();
$title = CRM_Utils_Array::value('title', $params);
if ($title) {
$clauses[] = "pcps.title LIKE %1";
if (strpos($title, '%') !== FALSE) {
$params[1] = array($title, 'String', FALSE);
}
else {
$params[1] = array($title, 'String', TRUE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are mixing 'general' params like 'title' with DAO formatted params (1 => array('title', 'String'). Can't we use 2 separate arrays? Preferably returning array($whereClause, $params) rather than passing by reference.

We haven't used this much but it's also possible to interpolate the params in-function by calling return CRM_Core_DAO::composeQuery($query, $params);

}
}
$pageType = CRM_Utils_Array::value('page_type', $params);
if ($pageType) {
$clauses[] = 'pcps.page_type LIKE %2';
$params[2] = array($pageType, 'String');
}
$status = CRM_Utils_Array::value('status_id', $params);
if ($status) {
$clauses[] = 'pcps.status_id = %3';
$params[3] = array($status, 'Integer');
}
$page_id = CRM_Utils_Array::value('page_id', $params);
if ($page_id) {
$clauses[] = 'pcps.page_id = %4 AND pcps.page_type = "contribute"';
$params[4] = array($page_id, 'Integer');
}
$event_id = CRM_Utils_Array::value('event_id', $params);
if ($event_id) {
$clauses[] = 'pcps.page_id = %5 AND pcps.page_type = "event"';
$params[5] = array($event_id, 'Integer');
}
$supporter = CRM_Utils_Array::value('supporter', $params);
if ($supporter) {
$clauses[] = "(pcp_supporter.sort_name LIKE %6 OR supporter_email.email LIKE %6)";
if (strpos($supporter, '%') !== FALSE) {
$params[6] = array($supporter, 'String', FALSE);
}
else {
$params[6] = array($supporter, 'String', TRUE);
}
}
$start_date = CRM_Utils_Array::value('start_date', $params);
if ($start_date) {
$clauses[] = '(event.registration_start_date >= %7 OR contribution_page.start_date >= %7)';
$params[7] = array(CRM_Utils_Date::processDate($start_date), 'String');
}
$end_date = CRM_Utils_Array::value('end_date', $params);
if ($end_date) {
$clauses[] = '(event.registration_end_date <= %8 OR contribution_page.end_date <= %8)';
$params[8] = array(CRM_Utils_Date::processDate($end_date), 'String');
}
if (empty($clauses)) {
$clauses[] = '1';
}
return implode(' AND ', $clauses);
}

public static function actionLinks() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment block missing

$links = array(
CRM_Core_Action::UPDATE => array(
'name' => ts('Edit'),
'url' => 'civicrm/pcp/info',
'qs' => 'action=update&reset=1&id=%%id%%&context=dashboard',
'title' => ts('Edit Personal Campaign Page'),
),
CRM_Core_Action::RENEW => array(
'name' => ts('Approve'),
'title' => ts('Approve Personal Campaign Page'),
),
CRM_Core_Action::REVERT => array(
'name' => ts('Reject'),
'title' => ts('Reject Personal Campaign Page'),
),
CRM_Core_Action::DELETE => array(
'name' => ts('Delete'),
'url' => 'civicrm/pcp',
'qs' => 'action=delete&id=%%id%%',
'title' => ts('Delete Personal Campaign Page'),
),
CRM_Core_Action::ENABLE => array(
'name' => ts('Enable'),
'ref' => 'crm-enable-disable',
'title' => ts('Enable'),
),
CRM_Core_Action::DISABLE => array(
'name' => ts('Disable'),
'ref' => 'crm-enable-disable',
'title' => ts('Disable'),
),
);
return $links;
}

}
Loading