Skip to content

Commit

Permalink
Merge pull request #26062 from aydun/daystoanniv
Browse files Browse the repository at this point in the history
API4: Add DAYSTOANNIV function
  • Loading branch information
colemanw authored Apr 17, 2023
2 parents 5c7f605 + 2e44c7c commit 4d56c38
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 2 deletions.
12 changes: 11 additions & 1 deletion Civi/Api4/Query/SqlFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* SqlFunction classes don't actually process data, SQL itself does the real work.
* The role of each SqlFunction class is to:
*
* 1. Whitelist the SQL function for use by APIv4 (it doesn't allow any that don't have a SQLFunction class).
* 1. Whitelist a standard SQL function, or define a custom one, for use by APIv4 (it doesn't allow any that don't have a SQLFunction class).
* 2. Document what the function does and what arguments it accepts.
* 3. Tell APIv4 how to treat the inputs and how to format the outputs.
*
Expand Down Expand Up @@ -153,6 +153,16 @@ public function render(Api4SelectQuery $query): string {
$output .= (strlen($output) ? ' ' : '') . $rendered;
}
}
return $this->renderExpression($output);
}

/**
* Render the final expression
*
* @param string $output
* @return string
*/
protected function renderExpression($output): string {
return $this->getName() . '(' . $output . ')';
}

Expand Down
60 changes: 60 additions & 0 deletions Civi/Api4/Query/SqlFunctionDAYSTOANNIV.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Api4\Query;

/**
* Sql function
*/
class SqlFunctionDAYSTOANNIV extends SqlFunction {

protected static $category = self::CATEGORY_DATE;

protected static $dataType = 'Integer';

protected static function params(): array {
return [
[
'max_expr' => 1,
'optional' => FALSE,
],
];
}

/**
* @return string
*/
public static function getTitle(): string {
return ts('Days to Anniversary');
}

/**
* @return string
*/
public static function getDescription(): string {
return ts('Number of days until the next anniversary of this date.');
}

/**
* @inheritDoc
*/
protected function renderExpression($output): string {
return "DATEDIFF(
IF(
DATE(CONCAT(YEAR(CURDATE()), '-', MONTH({$output}), '-', DAY({$output}))) < CURDATE(),
CONCAT(YEAR(CURDATE()) + 1, '-', MONTH({$output}), '-', DAY({$output})),
CONCAT(YEAR(CURDATE()), '-', MONTH({$output}), '-', DAY({$output}))
),
CURDATE()
)";
}

}
4 changes: 3 additions & 1 deletion tests/phpunit/api/v4/Action/ContactGetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,15 @@ public function testAge(): void {

$result = Contact::get(FALSE)
->addWhere('last_name', '=', $lastName)
->addSelect('first_name', 'age_years', 'next_birthday')
->addSelect('first_name', 'age_years', 'next_birthday', 'DAYSTOANNIV(birth_date)')
->execute()->indexBy('first_name');
$this->assertEquals(1, $result['abc']['age_years']);
$this->assertEquals(3, $result['abc']['next_birthday']);
$this->assertEquals(3, $result['abc']['DAYSTOANNIV:birth_date']);
$this->assertEquals(21, $result['def']['age_years']);
$this->assertEquals(0, $result['ghi']['age_years']);
$this->assertEquals(0, $result['ghi']['next_birthday']);
$this->assertEquals(0, $result['ghi']['DAYSTOANNIV:birth_date']);

Contact::get(FALSE)
->addWhere('age_years', '=', 21)
Expand Down

0 comments on commit 4d56c38

Please sign in to comment.