Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Prepare develop branch to target PHP 7.2 #80

Merged
merged 35 commits into from
Nov 29, 2018

Conversation

weierophinney
Copy link
Member

@weierophinney weierophinney commented Nov 19, 2018

To prepare for the 3.0 release (already begun with #14), this patch ups the minimum supported version of PHP to 7.2, and adds type hints, including object typehints. Additionally, a number of interfaces were written such as to allow optional parameters, but did not define them in the interface; this patch updates those to add the optional values as nullable value types.

PHP 7.2 was chosen as a target as it adds the object typehint, which helps us firm up the interfaces in this particular component tremendously, as extract() can now require an object, and hydrate() can both require accepting one as well as returning one.

TODO

  • Bump PHP requirement to 7.2
  • Add object typehints
  • Ensure unit tests work
  • Add PHPStan checks
  • Version documentation
  • Create migration document

@vaclavvanik
Copy link
Contributor

I would like to incorporate small update of DateTimeFormatterStrategy as I consulted with @froschdesign.

Should I wait when this PR will be merged?

Second I would to create DateTimeImmutableFormatterStrategy.

@weierophinney
Copy link
Member Author

@vaclavvanik I already merged that particular PR to the develop branch, on which this is based; if there are any additions you want to make to it, let me know!

As for an additional strategy - that can happen either after this is merged and before release, or as part of a 3.1.0 release (which we can do pretty quickly following).

@vaclavvanik
Copy link
Contributor

@weierophinney please update DateTimeFormatterStrategy::hydrate method to:

/**
 * Converts date time string to DateTime instance for injecting to object
 *
 * {@inheritDoc}
 *
 * @param null|string|DateTimeInterface $value
 * @param  array $data  The whole data is optionally provided as context.
 * @return null|string|DateTimeInterface
 * @throws Exception\InvalidArgumentException
 */
public function hydrate($value, ?array $data = null)
{
    if ($value === '' || $value === null || $value instanceof DateTimeInterface) {
        return $value;
    }

    if (! is_string($value)) {
        throw new Exception\InvalidArgumentException(sprintf(
            'Unable to hydrate. Expected null, string or DateTimeInterface. %s was given.',
            is_object($value) ? get_class($value) : gettype($value)
        ));
    }

    $hydrated = DateTime::createFromFormat($this->format, $value, $this->timezone);

    if ($hydrated === false && $this->dateTimeFallback) {
        $hydrated = new DateTime($value, $this->timezone);
    }

    return $hydrated ?: $value;
}

@weierophinney weierophinney force-pushed the feature/php-7.1-support branch 2 times, most recently from 625434c to 45cde68 Compare November 20, 2018 16:25
- Require at least PHP 7.1
- Require 3.X (or latest) versions of ZF components.
- Require PHPUnit 7.4
- Added `declare(strict_types=1)` to all classes

- Adds typehints to all parameters and return values. In addition, it
  expands interfaces that were allowing optional values to provide
  appropriate typehints. Also uses `object` typehints (nullable in some
  cases) where appropriate:
  - `HydrationInterface`
  - `ExtractionInterface`
  - `NamingStrategyInterface`
  - `StrategyInterface`
  - All classes implementing the above

- Calls to `getNamingStrategy()` must be preceded by `hasNamingStrategy()`,
  to ensure the method does not attempt to return `null` (which is now
  disallowed by the interface).

- Removes type check/throw combinations where typehints now make them obsolete.
  - Updates test expectations and/or removes tests to correspond with
    these changes.
  - Removes data provider entries that are no longer relevant.

- Removes annotations made redundant by typehints.

- Adds typehints for previously "mixed" types when we now know the type
  will not vary (e.g., `Reflection::getReflProperties()` can typehint
  `$input` against `object` now).

- Fixes `ClosureStrategy` to check if the composed extraction/hydration
  callback is actually set before attempting to call it; if not set, it
  returns the value verbatim instead.

- Fixes the `ExplodeStrategy` to cast the `$value` to `string` during
  hydration when calling `explode()`. This preserves previous behavior.

- Removes tests against zend-servicemanager v2 (affects
  `DelegatingHydratorFactory` and `HydratorPluginManager` and related
  factory.
- Return value verbatim when empty string, null, or a `DateTimeInterface` instance.
- Raise an exception for other non-string values.

Also modified the case when hydration fails to vary how the `DateTime`
instance is created based on whether or not a timezone is present.
@weierophinney weierophinney changed the title Prepare develop branch to target PHP 7.1 or 7.2 Prepare develop branch to target PHP 7.2 Nov 20, 2018
@weierophinney
Copy link
Member Author

@vaclavvanik Made the changes requested, along with additional unit tests.

- Mark the "Home" page
- Remove the copyright configuration; no longer needed
- Sync site_description to package descripiton
@weierophinney weierophinney added this to the 3.0.0 milestone Nov 20, 2018
@vaclavvanik
Copy link
Contributor

@weierophinney awesome. +1

@vaclavvanik
Copy link
Contributor

@weierophinney I looked at bakura v3 hydrator for inspiration when v3 is comming.

Bakura created Hydrator\NamingStrategy\ProvidesNamingStrategyTrait and Hydrator\Strategy\ProvidesStrategyTrait. It looks it simplifies creating own hydrators (which does not extend AbstractHydrator).

@thomasvargiu
Copy link

@weierophinney Could be useful to add phpstan in the CI for this kind of changes? It's useful when using type hints.

@Ocramius
Copy link
Member

Ocramius commented Nov 21, 2018 via email

- Adds phpstan as a development requirement
- Adds phpstan configuration at level 7, scanning the src tree
- Incorporates phpstan into the Travis CI workflow
- A number or properties are stored as `ArrayObject` instances, but we
  were performing various unsupported array operations on them.
- Adds zend-modulemanager as a dependency, to eliminate issues with the `Module` class.
- Some property annotations were incorrect; updating them to allow known
  types fixed errors.
- Some parameter annotations were incorrect.
- Raise an exception from `getNamingStrategy()` if no naming strategy is present.
- Subclasses should generally call the parent constructor.
- Replace `is_callable()` with `method_exists()` everywhere.
- Remove casting during assignments when the type is known.
- Do `$serializer` assignment within
  `SerializableStrategy::getSerializer()` to prevent incorrect detection
  of string as a type for `$serializer` after lazy loading

I've added three `ignoreErrors` directives:

- One property is set correctly, and assignments are correct, but
  phpstan cannot seem to determine that an assignment is valid.
- We are passing a PSR-11 container to plugin managers,
  which is always valid within this context (it will also fulfill a
  typehint the plugin manager accepts in all situations), but phpstan
  does not know the context, so assumes an error is present.
- A number of `||` and `&&` conditionals are flagged as always returning
  true or false, but they can actually vary.
@weierophinney
Copy link
Member Author

@Ocramius Just pushed a changeset that includes phpstan checks. I had to create a few exclusions (<rant>could not figure out valid YAML to make the exclusions file-specific</rant>), but surprisingly few; the commit details which and why.

@weierophinney
Copy link
Member Author

Bakura created Hydrator\NamingStrategy\ProvidesNamingStrategyTrait and Hydrator\Strategy\ProvidesStrategyTrait. It looks it simplifies creating own hydrators (which does not extend AbstractHydrator).

We can add these in a later patch; right now, focusing on getting the existing functionality updated.

- Creates both `v2/` and `v3/` trees in the documentation, based on 2.4.1 docs.
- Makes all existing docs into redirects, redirecting to the v2 docs.
- Updates the `mkdocs.yml`:
  - Makes the top-level navigation items point to the v3 artifacts.
  - Adds a `v2` navigation item, with subitems pointing to the v2 docs.
  - Adds hidden pages pointing to the legacy locations, to allow redirects.

**NOTE**: No `v1/` tree is created, as that version did not have ship
documentation within the repository.
mkdocs.yml Outdated Show resolved Hide resolved
@froschdesign
Copy link
Member

@weierophinney
I'm working on the documentation content. I have already written code examples for all hydrators and most of the strategies. Maybe I'm ready in the next two days, but you do not have to wait with the release of version 3.

Both `ExtractEvent` and `HydrateEvent` were defining `object` parameters
and return types via annotations, but could easily define them
explicitly as typehints.
Allows greater compatibility with installs of mkdocs.
@weierophinney
Copy link
Member Author

I also saw that many native functions are not imported.

Can you expand on this? I did a thorough audit yesterday. I did not import functions in the test suite because it's basically unnecessary; however, the src/ tree should be fully covered at this point.

I did another pass on the src/ tree and found a handful of unimported global functions. I'm fairly confident they're all imported now.

Copy link

@thomasvargiu thomasvargiu left a comment

Choose a reason for hiding this comment

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

Little improvements in code. Nothing important.

What should we do with phpdoc? Are we using it partially because we are using type hints?
There are many methods with no phpdoc @param (or @return) or with partial declared parameters. Using php-cs-fixer or PhpStorm inspections can help to identify them.

src/Strategy/ExplodeStrategy.php Outdated Show resolved Hide resolved
src/AbstractHydrator.php Show resolved Hide resolved
src/Exception/InvalidCallbackException.php Show resolved Hide resolved
src/Iterator/HydratingArrayIterator.php Outdated Show resolved Hide resolved
src/NamingStrategy/ArrayMapNamingStrategy.php Outdated Show resolved Hide resolved
src/NamingStrategy/ArrayMapNamingStrategy.php Outdated Show resolved Hide resolved
src/NamingStrategy/CompositeNamingStrategy.php Outdated Show resolved Hide resolved
src/NamingStrategy/CompositeNamingStrategy.php Outdated Show resolved Hide resolved
src/NamingStrategy/CompositeNamingStrategy.php Outdated Show resolved Hide resolved
src/NamingStrategy/NamingStrategyInterface.php Outdated Show resolved Hide resolved
src/Strategy/DateTimeFormatterStrategy.php Show resolved Hide resolved
src/Strategy/DateTimeFormatterStrategy.php Show resolved Hide resolved
src/Strategy/DateTimeFormatterStrategy.php Show resolved Hide resolved
src/Filter/OptionalParametersFilter.php Show resolved Hide resolved
src/Iterator/HydratingIteratorIterator.php Show resolved Hide resolved
Incorporates all feedback except ensuring license docblocks are
up-to-date with regards to format.
@weierophinney
Copy link
Member Author

@thomasvargiu

What should we do with phpdoc? Are we using it partially because we are using type hints?
There are many methods with no phpdoc @param (or @return) or with partial declared parameters. Using php-cs-fixer or PhpStorm inspections can help to identify them.

We do not need to declare annotations for parameters or return values that have type hints, unless we want to add descriptions to them; otherwise, they are redundant. PHPDoc and IDEs will pick up the declared typehints when no annotations exist. (They will also correctly mix-and-match declared typehints with annotations provided in order to provide the full signature.)

We use phpcs, but do not currently have a ruleset that will populate them; IIRC, v2 of our ruleset will include this.

@thomasvargiu
Copy link

It just was a question to know it. Default PhpStorm inspections give a warning about them (I’m not saying it’s correct).
It’s not a problem but it’s weird to see that when a method has 4 parameters, only 3 of them have phpdoc @param. I would like to try to generate php documentation to see what result is.

@Ocramius
Copy link
Member

Ocramius commented Nov 28, 2018 via email

Referencing a function by string automatically assumes it is globally
qualified.
In English, we typically sort such that letters have precedence over
symbols; however, in computers, this is evidently exactly the opposite.
Since computers do the automation, we go with what they do. *sigh*
@Ocramius Ocramius self-assigned this Nov 29, 2018
Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

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

🚢

@Ocramius Ocramius merged commit 34fe752 into zendframework:develop Nov 29, 2018
"php": "^5.6 || ^7.0",
"zendframework/zend-stdlib": "^3.0"
"php": "^7.2",
"zendframework/zend-stdlib": "^3.2.1"
Copy link
Contributor

Choose a reason for hiding this comment

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

Mb_* functions are used (at least in UnderscoreNamingStrategy\CamelCaseToUnderscoreFilter.php)
Imo we should require ext-mbstring

Copy link
Member

Choose a reason for hiding this comment

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

@vaclavvanik
Please create a pull request and use the develop branch for your improvement. This PR is merged and finished.

Copy link
Contributor

Choose a reason for hiding this comment

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

i create it tomorrow. today i am sick :-/

Copy link
Member Author

Choose a reason for hiding this comment

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

We test to see if those functions are available before using them, defaulting to the non-mb variants if they are not. As such, there is no hard requirement on ext-mbstring.

weierophinney added a commit that referenced this pull request Nov 29, 2018
@weierophinney weierophinney deleted the feature/php-7.1-support branch November 29, 2018 14:13
weierophinney added a commit to weierophinney/zend-hydrator that referenced this pull request Dec 3, 2018
weierophinney added a commit to weierophinney/zend-hydrator that referenced this pull request Dec 3, 2018
weierophinney added a commit to weierophinney/zend-hydrator that referenced this pull request Dec 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants