Skip to content
Merged
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
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: CI

on:
push:
pull_request:

jobs:
static-analysis:
name: Static Analysis
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup PHP 8.1
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: composer

- name: Install dependencies
run: composer install --prefer-dist --no-interaction

- name: Run PHPStan
run: composer phpstan

- name: Run PHPCS
run: composer phpcs

phpunit:
name: PHPUnit (PHP ${{ matrix.php }} + ORM ${{ matrix.orm }})
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
include:
# ORM 4 requires PHP >= 7.2
- { php: '7.4', orm: '4' }
- { php: '8.0', orm: '4' }
- { php: '8.1', orm: '4' }
- { php: '8.2', orm: '4' }
- { php: '8.3', orm: '4' }
- { php: '8.4', orm: '4' }

# ORM 5 requires PHP >= 8.1
- { php: '8.1', orm: '5' }
- { php: '8.2', orm: '5' }
- { php: '8.3', orm: '5' }
- { php: '8.4', orm: '5' }

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer

- name: Install base dependencies
run: composer install --prefer-dist --no-interaction

- name: Require CakePHP ORM version
run: composer require "cakephp/orm:^${{ matrix.orm }}" "cakephp/database:^${{ matrix.orm }}" --no-interaction --no-update

- name: Update dependencies
run: composer update --prefer-dist --no-interaction

- name: Run PHPUnit
run: composer phpunit-coverage
13 changes: 8 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@
"type": "library",
"require": {
"php": ">=7.4.0",
"cakephp/database": "^4.0",
"cakephp/orm": "^4.0"
"cakephp/database": "^4.0|^5.0",
"cakephp/orm": "^4.0|^5.0"
},
"require-dev": {
"phpstan/phpstan": "^2.0.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan": "^1.0|^2.0",
"phpstan/phpstan-phpunit": "^1.0|^2.0",
"phpunit/phpunit": "^8.5 || ^9.3",
"squizlabs/php_codesniffer": "^4.0"
},
"autoload": {
"psr-4": {
"Bancer\\NativeQueryMapper\\": "src/"
}
},
"files": [
"src/polyfill_str_contains.php"
]
},
"autoload-dev" : {
"psr-4" : {
Expand Down
25 changes: 11 additions & 14 deletions src/ORM/AutoHydratorRecursive.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Bancer\NativeQueryMapper\ORM;

use Cake\Database\StatementInterface;
use Cake\Datasource\EntityInterface;
use Cake\ORM\Table;
use Cake\ORM\Entity;
Expand Down Expand Up @@ -141,7 +140,7 @@ public function hydrateMany(array $rows): array
$results = [];
$rootAlias = $this->rootTable->getAlias();
foreach ($rows as $row) {
$tree = $this->buildEntityRecursive($this->rootTable, $row, $rootAlias);
$tree = $this->buildEntityRecursive($this->rootTable, $row);
$root = $tree[$rootAlias];
$key = $this->entityKey($root, $this->rootTable);
if (!isset($results[$key])) {
Expand All @@ -156,14 +155,12 @@ public function hydrateMany(array $rows): array
/**
* @param Table $table
* @param mixed[] $row
* @param string $expectedAlias
* @param mixed[] $visited
* @return \Cake\Datasource\EntityInterface[]
*/
protected function buildEntityRecursive(
Table $table,
array $row,
string $expectedAlias,
array &$visited = []
): array {
$alias = $table->getAlias();
Expand Down Expand Up @@ -203,7 +200,7 @@ protected function buildEntityRecursive(
continue;
}
if ($assoc instanceof HasMany) {
$tree = $this->buildEntityRecursive($target, $row, $childAlias, $visited);
$tree = $this->buildEntityRecursive($target, $row, $visited);
if ($tree) {
$list = $entity->get($assoc->getProperty());
if (!is_array($list)) {
Expand All @@ -216,25 +213,25 @@ protected function buildEntityRecursive(
continue;
}
if ($assoc instanceof BelongsTo || $assoc instanceof HasOne) {
$tree = $this->buildEntityRecursive($target, $row, $childAlias, $visited);
$tree = $this->buildEntityRecursive($target, $row, $visited);
if ($tree) {
$entity->set($assoc->getProperty(), $tree[$childAlias]);
$out += $tree;
}
continue;
}
if ($assoc instanceof BelongsToMany) {
$junctionAlias = $assoc->getThrough();
if (is_object($junctionAlias)) {
$junctionAlias = $junctionAlias->getAlias();
}
$tree = $this->buildEntityRecursive($target, $row, $childAlias, $visited);
$tree = $this->buildEntityRecursive($target, $row, $visited);
if ($tree) {
$child = $tree[$childAlias];
$junctionAlias = $assoc->getThrough();
if (is_object($junctionAlias)) {
$junctionAlias = $junctionAlias->getAlias();
}
// hydrate join data only if the row contains it
if (isset($this->aliasMap[$junctionAlias])) {
if ($junctionAlias !== null && isset($this->aliasMap[$junctionAlias])) {
$junctionTable = TableRegistry::getTableLocator()->get($junctionAlias);
$jTree = $this->buildEntityRecursive($junctionTable, $row, $junctionAlias, $visited);
$jTree = $this->buildEntityRecursive($junctionTable, $row, $visited);
if ($jTree) {
$child->set('_joinData', $jTree[$junctionAlias]);
$out += $jTree;
Expand All @@ -251,7 +248,7 @@ protected function buildEntityRecursive(
continue;
}
// fallback
$tree = $this->buildEntityRecursive($target, $row, $childAlias, $visited);
$tree = $this->buildEntityRecursive($target, $row, $visited);
if ($tree) {
$entity->set($assoc->getProperty(), $tree[$childAlias]);
$out += $tree;
Expand Down
11 changes: 11 additions & 0 deletions src/polyfill_str_contains.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

if (!function_exists('str_contains')) {
/**
* Polyfill for PHP 8 str_contains() for PHP 7.4.
*/
function str_contains(string $haystack, string $needle): bool
{
return $needle === '' || strpos($haystack, $needle) !== false;
}
}
1 change: 1 addition & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
]);
ConnectionManager::alias('test', 'default');

/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get('test');

$connection->execute("
Expand Down