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

bump to php7.4 #24

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ services:
{
/**
* @var string
* @Column(name="title", type="string", nullable=false)
* [#Column(name:"title", type:"string", nullable:false)]
*/
private $title;
private string $title;

/**
* @var TsVector
Expand All @@ -84,9 +84,9 @@ services:

/**
* @var string
* @Column(name="body", type="text", nullable=true)
* [#Column(name:"body", type:"text", nullable:true)]
*/
private $body;
private ?string $body;

/**
* @var TsVector
Expand Down
16 changes: 11 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@
"license": "MIT",
"type": "library",
"require": {
"doctrine/orm": "~2.4",
"php": ">=5.4"
"doctrine/orm": "^2.10 || ^3.0",
"php": ">=8.0"
},
"require-dev": {
"phpunit/phpunit": "~4.4",
"phpunit/phpunit-mock-objects": "~2.3"
"phpunit/phpunit": "*",
"phpunit/phpunit-mock-objects": "*",
"rector/rector": "^0.13.8",
"symfony/cache": "^6.3 || ^7.0"
},
"autoload": {
"psr-4": {
"VertigoLabs\\DoctrineFullTextPostgres\\": "src/"
}
},
"minimum-stability": "dev"
"autoload-dev": {
"psr-4": {
"Base\\": "tests/VertigoLabs/Base"
}
}
}
9 changes: 9 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
parameters:
level: 0
# inferPrivatePropertyTypeFromConstructor: true
paths:
- ./src
excludePaths:
- 'src/Resources/skeleton'
- */cache/*

10 changes: 3 additions & 7 deletions tests/phpunit.xml → phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExections="true"
convertNoticesToExecptions="true"
convertWarningsToExeceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./bootstrap.php">
stopOnFailure="true"
bootstrap="./tests/bootstrap.php">
<testsuites>
<testsuite name="TsVector Extension">
<directory suffix="Test.php">./VertigoLabs/TsVector</directory>
Expand All @@ -20,4 +16,4 @@
<directory suffix="Test.php">./VertigoLabs/TsRank</directory>
</testsuite>
</testsuites>
</phpunit>
</phpunit>
23 changes: 23 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\PHPUnit\Set\PHPUnitSetList;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src'
]);

// register a single rule
// $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);

// define sets of rules
$rectorConfig->sets([
PHPUnitSetList::PHPUNIT_80,
LevelSetList::UP_TO_PHP_74
]);
};
30 changes: 30 additions & 0 deletions rector.sav
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Php74\Rector\Property\TypedPropertyRector;
use Rector\Set\ValueObject\LevelSetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Rector\PHPUnit\Set\PHPUnitSetList;

return static function (ContainerConfigurator $containerConfigurator): void {
// get parameters
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/tests',
__DIR__ . '/src',
]);

// Define what rule sets will be applied

// rector.php
// $containerConfigurator->import(LevelSetList::UP_TO_PHP_74);
$containerConfigurator->import(PHPUnitSetList::PHPUNIT_50);

// get services (needed for register a single rule)
// $services = $containerConfigurator->services();

// register a single rule
// $services->set(TypedPropertyRector::class);
};
103 changes: 84 additions & 19 deletions src/Common/TsVectorSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace VertigoLabs\DoctrineFullTextPostgres\Common;

use App\Entity\Media;
Copy link
Owner

Choose a reason for hiding this comment

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

This line shouldn't exist

use Doctrine\Common\Annotations\AnnotationException;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
Expand Down Expand Up @@ -60,7 +61,7 @@ public function __construct()
*
* @return array
*/
public function getSubscribedEvents()
public function getSubscribedEvents(): array
{
return [
Events::loadClassMetadata,
Expand All @@ -73,9 +74,40 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/** @var ClassMetadata $metaData */
$metaData = $eventArgs->getClassMetadata();

$class = $metaData->getReflectionClass();

foreach ($class->getProperties() as $prop) {
// check for php8 attributes on the class properties
if (method_exists($prop, 'getAttributes')) {
foreach ($prop->getAttributes() as $reflectionAttribute) {
if ($reflectionAttribute->getName() === TsVector::class) {
// /** @var TsVector $attribute */
$attribute = new ($reflectionAttribute->getName())(...$reflectionAttribute->getArguments()); // crazy, something is wrong here.
Copy link
Owner

Choose a reason for hiding this comment

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

I'm a little apprehensive about this comment!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No doubt! I'll see if I can figure it out. I'm fighting a little bit with supporting both attributes and annotations, I think that attributes should take priority if both exist.

$this->checkWatchFields($class, $prop, $attribute);

$metaData->mapField([
'fieldName' => $prop->getName(),
'columnName' => $this->getColumnName($prop, $attribute),
'type' => 'tsvector',
'weight' => strtoupper($attribute->weight),
'language' => strtolower($attribute->language),
'nullable' => true, // pre-populating $this->isWatchFieldNullable($class, $attribute)
]);

}
}
}

// $this->checkWatchFields($class, $prop, $attribute);
// $metaData->mapField([
// 'fieldName' => $prop->getName(),
// 'columnName' => $this->getColumnName($prop, $annotation),
// 'type' => 'tsvector',
// 'weight' => strtoupper($annotation->weight),
// 'language' => strtolower($annotation->language),
// 'nullable' => $this->isWatchFieldNullable($class, $annotation)
// ]);

Comment on lines +101 to +110
Copy link
Owner

Choose a reason for hiding this comment

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

Commented out code should be removed

/** @var TsVector $annotation */
$annotation = $this->reader->getPropertyAnnotation($prop, self::ANNOTATION_NS.self::ANNOTATION_TSVECTOR);
if (null === $annotation) {
Expand Down Expand Up @@ -161,30 +193,53 @@ private function getColumnName(\ReflectionProperty $property, TsVector $annotati
return $name;
}

private function checkWatchFields(\ReflectionClass $class, \ReflectionProperty $targetProperty, TsVector $annotation)
private function checkWatchFields(\ReflectionClass $reflectionClass, \ReflectionProperty $targetProperty, TsVector $annotation)
{
foreach ($reflectionClass->getAttributes(\VertigoLabs\DoctrineFullTextPostgres\ORM\Attribute\TsVector::class) as $attribute) {
dd($attribute);
}

foreach ($annotation->fields as $fieldName) {
if ($class->hasMethod($fieldName)) {
if ($reflectionClass->hasMethod($fieldName)) {
continue;
}

if (!$class->hasProperty($fieldName)) {
if (!$reflectionClass->hasProperty($fieldName)) {
throw new MappingException(sprintf('Class does not contain %s property or getter', $fieldName));
}

$property = $class->getProperty($fieldName);
$reflectionProperty = $reflectionClass->getProperty($fieldName);

/** @var Column $propAnnot */
$propAnnot = $this->reader->getPropertyAnnotation($property, Column::class);
if (!in_array($propAnnot->type, self::$supportedTypes)) {
throw new AnnotationException(sprintf(
'%s::%s TsVector field can only be assigned to ( "%s" ) columns. %1$s::%s has the type %s',
$class->getName(),
$targetProperty->getName(),
implode('" | "', self::$supportedTypes),
$fieldName,
$propAnnot->type
));
if (!$propAnnot = $this->reader->getPropertyAnnotation($reflectionProperty, Column::class)) {
foreach ($reflectionProperty->getAttributes(Column::class) as $columnAttribute) {
if (!in_array($columnAttribute->getArguments()['type'], self::$supportedTypes)) {
throw new AnnotationException(sprintf(
'%s::%s TsVector field can only be assigned to ( "%s" ) columns. %1$s::%s has the type %s',
$reflectionClass->getName(),
$targetProperty->getName(),
implode('" | "', self::$supportedTypes),
$fieldName,
$propAnnot->type
));
}

}
} else {
// use annotation
if (!in_array($propAnnot->type, self::$supportedTypes)) {
throw new AnnotationException(sprintf(
'%s::%s TsVector field can only be assigned to ( "%s" ) columns. %1$s::%s has the type %s',
$reflectionClass->getName(),
$targetProperty->getName(),
implode('" | "', self::$supportedTypes),
$fieldName,
$propAnnot->type
));
}
}


}
}

Expand All @@ -197,9 +252,19 @@ private function isWatchFieldNullable(\ReflectionClass $class, TsVector $annotat

$property = $class->getProperty($fieldName);
/** @var Column $propAnnot */
$propAnnot = $this->reader->getPropertyAnnotation($property, Column::class);
if (false === $propAnnot->nullable) {
return false;
if ($propAnnot = $this->reader->getPropertyAnnotation($property, Column::class)) {
if (false === $propAnnot->nullable) {
return false;
}
} else {
$reflectionProperty = $class->getProperty($fieldName);
foreach ($reflectionProperty->getAttributes(Column::class) as $propAttr) {
$attr = $propAttr->getArguments();
if (false === $attr['nullable'] ?? false) {
return false;
}

}
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/DBAL/Types/TsVector.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $pla
return 'tsvector';
}

public function canRequireSQLConversion()
public function canRequireSQLConversion(): bool
{
return true;
}
Expand Down Expand Up @@ -59,14 +59,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
*
* @return mixed the database representation of the value
*/
public function convertToDatabaseValueSQL($sqlExp, AbstractPlatform $platform)
public function convertToDatabaseValueSQL($sqlExp, AbstractPlatform $platform): string
{
return sprintf("to_tsvector('english', ?)", $sqlExp);
return sprintf("to_tsvector('english', %s)", $sqlExp);
}

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value['data'];
if ($value) {
return $value['data'];
}
}

/**
Expand Down
42 changes: 19 additions & 23 deletions src/ORM/Mapping/TsVector.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,29 @@

namespace VertigoLabs\DoctrineFullTextPostgres\ORM\Mapping;

use Doctrine\Common\Annotations\Annotation;
use Doctrine\Common\Annotations\Annotation\Target;
//use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
use \Attribute;
use Doctrine\ORM\Mapping\MappingAttribute;

/**
* Class TsVector.
*
* @Annotation
* @Target("PROPERTY")
*/
final class TsVector extends Annotation
#[Attribute(Attribute::TARGET_PROPERTY)]
final class TsVector implements MappingAttribute
{
/**
* @var array<string>
* @Annotation\Required()
*/
public $fields = [];
/**
* @var string
*/
public $name;
/**
* @var string
* @Annotation\Enum({"A","B","C","D"})
*/
public $weight = 'D';
/**
* @var string
*/
public $language = 'english';
public function __construct(public string $name, public array $fields=[], public string $weight='D', public string $language = 'english')
{
}

public function getWeight(): string
{
return $this->weight;
}

public function getLanguage(): string
{
return $this->language;
}

}
Loading