Skip to content

Commit

Permalink
Merge pull request #140 from 5pm-HDH/feat/song-statistic
Browse files Browse the repository at this point in the history
feat(song-statistic): add song-statistic
  • Loading branch information
DumbergerL authored Apr 26, 2023
2 parents 2d52bf0 + 2a2e304 commit c4bf704
Show file tree
Hide file tree
Showing 13 changed files with 667 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added
- Add Address-Property to Appointment ([PR137](https://github.com/5pm-HDH/churchtools-api/pull/137))
- Add SongStatistic ([PR140](https://github.com/5pm-HDH/churchtools-api/pull/140))

### Changed

Expand Down
94 changes: 94 additions & 0 deletions docs/out/SongAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,97 @@ The method returns a nullable [File-Model](/../../src/Models/File.php).

```

## Retrieve Song Statistics

**Get All Statistics:**

```php
use CTApi\Requests\SongRequest;
use CTApi\Requests\SongStatisticRequest;
use CTApi\Requests\SongStatisticRequestBuilder;

$data = SongStatisticRequest::all();

$songStatistic = end($data);

var_dump( $songStatistic->getCount());
// Output: 14

var_dump( $songStatistic->getCountForCalendars([1, 2]));
// Output: 11


$song = $songStatistic->requestSong();

// Retrieve Dates:
$allDates = $songStatistic->getDates();
$date = end($allDates);
var_dump( $date["date"]);
// Output: '2021-12-12 10:30:00'

var_dump( $date["calendar_id"]);
// Output: '3'


$datesForMyServies = $songStatistic->getDatesForCalendars([1, 2]);
$dateService = end($datesForMyServies);
var_dump( $dateService["date"]);
// Output: '2021-07-11 10:30:00'

var_dump( $dateService["calendar_id"]);
// Output: '2'


```

**Get Statistics for Song:**

```php
use CTApi\Requests\SongRequest;
use CTApi\Requests\SongStatisticRequest;
use CTApi\Requests\SongStatisticRequestBuilder;

$song = SongRequest::findOrFail(21);
$statistics = $song->requestSongStatistic();

var_dump( 8);
// Output: $statistics?->getCount()

var_dump( 5);
// Output: $statistics?->getCountForCalendars([2])

var_dump( 0);
// Output: $statistics?->getCountForCalendars([21])


```

**Lazy-Builder:**

```php
use CTApi\Requests\SongRequest;
use CTApi\Requests\SongStatisticRequest;
use CTApi\Requests\SongStatisticRequestBuilder;

/**
* Lazy-SongStatisticRequestBuilder
*/
$requestBuilderLazy = new SongStatisticRequestBuilder(); // default: lazy-flag is true

$requestBuilderLazy->find("21");
$requestBuilderLazy->find("22");

// The whole song-statistic will be fetched ones and used for both "find"-calls.

/**
* Not-Lazy-SongStatisticRequestBuilder
*/

$requestBuilderNotLazy = new SongStatisticRequestBuilder(false);

$requestBuilderLazy->find("21");
$requestBuilderLazy->find("22");

// The whole song-statistic will be fetched for every "find"-call.

```
13 changes: 13 additions & 0 deletions docs/src/ressources/SongAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,16 @@ The method returns a nullable [File-Model](/../../src/Models/File.php).

{{ \Tests\Unit\Docs\CcliRequestTest.testRetrieveChordsheet }}

## Retrieve Song Statistics

**Get All Statistics:**

{{ \Tests\Unit\Docs\SongStatisticRequestTest.testGetAll }}

**Get Statistics for Song:**

{{ \Tests\Unit\Docs\SongStatisticRequestTest.testGetViaSong }}

**Lazy-Builder:**

{{ \Tests\Unit\Docs\SongStatisticRequestTest.testLazy }}
9 changes: 9 additions & 0 deletions src/Models/Song.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use CTApi\Models\Traits\FillWithData;
use CTApi\Models\Traits\MetaAttribute;
use CTApi\Requests\SongRequest;
use CTApi\Requests\SongStatisticRequest;

class Song extends AbstractModel implements UpdatableModel
{
Expand Down Expand Up @@ -101,6 +102,14 @@ public function requestSelectedArrangement(): ?SongArrangement
return $selectedArrangement;
}

public function requestSongStatistic(): ?SongStatistic
{
if($this->getId() != null){
return SongStatisticRequest::find($this->getIdOrFail());
}
return null;
}

/**
* @param string|null $id
* @return Song
Expand Down
95 changes: 95 additions & 0 deletions src/Models/SongStatistic.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php


namespace CTApi\Models;


use CTApi\Models\Traits\FillWithData;
use CTApi\Requests\SongRequest;

class SongStatistic
{
use FillWithData;

protected ?string $songId;
protected array $dates = [];

public static function createModelFromAjaxData(string $songId, array $dates): SongStatistic
{
$statistics = new SongStatistic();
return $statistics->setSongId($songId)
->setDates($dates);
}

public function requestSong(): ?Song
{
if(!is_null($this->songId)){
return SongRequest::find((int) $this->songId);
}
return null;
}

public function getDates(): array
{
return $this->dates;
}

public function getCount(): int
{
return sizeof($this->getDates());
}

public function getDatesForCalendars(array $calendarIds): array
{
return array_values(array_filter($this->dates, function ($element) use ($calendarIds) {
return in_array($element["calendar_id"], $calendarIds);
}));
}

public function getCountForCalendars(array $calendarIds): int
{
return sizeof($this->getDatesForCalendars($calendarIds));
}

public function toData(): array
{
$data = $this->convertPropertiesToData();
return array_merge(
$data,
['count' => $this->getCount()]
);
}

/**
* @return string|null
*/
public function getSongId(): ?string
{
return $this->songId;
}

/**
* @param string|null $songId
* @return SongStatistic
*/
public function setSongId(?string $songId): SongStatistic
{
$this->songId = $songId;
return $this;
}

/**
* @param array $dates
* @return SongStatistic
*/
public function setDates(array $dates): SongStatistic
{
$this->dates = array_map(function ($element) {
return [
'date' => $element['date'] ?? null,
'calendar_id' => $element['category_id'] ?? null
];
}, $dates);
return $this;
}
}
26 changes: 26 additions & 0 deletions src/Requests/SongStatisticRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php


namespace CTApi\Requests;


use CTApi\Models\Song;
use CTApi\Models\SongStatistic;

class SongStatisticRequest
{
public static function all(): array
{
return (new SongStatisticRequestBuilder())->all();
}

public static function findOrFail(string $id): SongStatistic
{
return (new SongStatisticRequestBuilder())->findOrFail($id);
}

public static function find(string $id): ?SongStatistic
{
return (new SongStatisticRequestBuilder())->find($id);
}
}
68 changes: 68 additions & 0 deletions src/Requests/SongStatisticRequestBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php


namespace CTApi\Requests;


use CTApi\Exceptions\CTRequestException;
use CTApi\Models\SongStatistic;
use CTApi\Requests\Traits\AjaxApi;
use CTApi\Utils\CTResponseUtil;

class SongStatisticRequestBuilder
{
use AjaxApi;

private array $data = [];

/**
* SongStatisticRequestBuilder constructor.
* @param bool $isLazy determine if builder requests statistic-data for every request new
*/
public function __construct(
private bool $isLazy = true
)
{
}

private function getStatisticData(): array
{
if($this->isLazy && !empty($this->data)){
return $this->data;
}else{
$response = $this->requestAjax("churchservice/ajax", "getSongStatistic", []);
$this->data = CTResponseUtil::dataAsArray($response);
return $this->data;
}
}

public function findOrFail(string $songId)
{
$model = $this->find($songId);
if ($model != null) {
return $model;
} else {
throw CTRequestException::ofModelNotFound(SongStatistic::class);
}
}

public function find(string $songId): ?SongStatistic
{
$data = $this->getStatisticData();
if(array_key_exists($songId, $data)){
return SongStatistic::createModelFromAjaxData($songId, $data[$songId]);
}
return null;
}

public function all(): array
{
$data = $this->getStatisticData();
$modelArray = [];
foreach($data as $songId => $dates)
{
$modelArray[] = SongStatistic::createModelFromAjaxData($songId, $dates);
}
return $modelArray;
}
}
46 changes: 46 additions & 0 deletions tests/integration/Requests/SongStatisticRequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php


namespace Tests\Integration\Requests;


use CTApi\CTLog;
use CTApi\Models\SongStatistic;
use CTApi\Requests\SongRequest;
use CTApi\Requests\SongStatisticRequest;
use Tests\Integration\TestCaseAuthenticated;
use Tests\Integration\TestData;

class SongStatisticRequestTest extends TestCaseAuthenticated
{
private int $songId;

protected function setUp(): void
{
if (!TestData::getValue("SONG_STATISTICS") == "YES") {
$this->markTestSkipped("Test suite is disabled in testdata.ini");
}
$this->songId = TestData::getValueAsInteger("SONG_STATISTICS_SONG_ID");
}

public function testRequestAll()
{
$data = SongStatisticRequest::all();

$this->assertNotEmpty($data);

$lastSongStatisticElement = end($data);
$this->assertNotEmpty($lastSongStatisticElement);
$this->assertInstanceOf(SongStatistic::class, $lastSongStatisticElement);
}

public function testRequestSong()
{
CTLog::enableHttpLog();
$song = SongRequest::findOrFail($this->songId);
$songStatistic = $song->requestSongStatistic();

$this->assertNotNull($songStatistic);
$this->assertEquals($songStatistic->getCount(), sizeof($songStatistic->getDates()));
}
}
4 changes: 4 additions & 0 deletions tests/integration/testdata.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ SONG_ARRANGEMENT_UPDATE_SONG_ID = 24
SONG_UPDATE = YES
SONG_UPDATE_SONG_ID = 24

# enable SONG_STATISTICS testsuite with YES and siable with NO
SONG_STATISTICS = YES
SONG_STATISTICS_SONG_ID = 10

# enable GROUP_MEMBER_UPDATE testsuite with YES and disable with NO
GROUP_MEMBER_UPDATE = YES
GROUP_MEMBER_UPDATE_GROUP_ID = 78
Expand Down
Loading

0 comments on commit c4bf704

Please sign in to comment.