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

feat: Test Rector to upgrade code for PHP 8.1 #2977

Merged
merged 13 commits into from
May 15, 2024
43 changes: 43 additions & 0 deletions .github/workflows/php-rector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: PHP Rector

on:
push:
branches:
- master
Levdbas marked this conversation as resolved.
Show resolved Hide resolved
- 2.x
paths:
- '**.php'
- '**composer.json'
pull_request:
branches:
- master
Levdbas marked this conversation as resolved.
Show resolved Hide resolved
- 2.x
paths:
- '**.php'
- '**composer.json'
types:
- opened
- synchronize
- ready_for_review

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
php-cs:
name: PHP Rector
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install dependencies
uses: ./.github/actions/setup

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44

- name: Run Rector checks
if: steps.changed-files.outputs.all_changed_files != ''
run: ./vendor/bin/rector process --dry-run ${{ steps.changed-files.outputs.files }}
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.7",
"phpunit/phpunit": "^9.0",
"rector/rector": "^1.0",
"squizlabs/php_codesniffer": "^3.0",
"symplify/easy-coding-standard": "^12.0",
"szepeviktor/phpstan-wordpress": "^1.1",
Expand Down Expand Up @@ -120,6 +121,8 @@
"@test",
"@cs"
],
"rector": "rector process --dry-run",
"rector:fix": "rector process",
"test": [
"@test:integration:acf",
"@test:integration:coauthors-plus",
Expand All @@ -145,6 +148,8 @@
"lint-composer": "Check composer.json for incorrect order and whitespace",
"lint-composer:fix": "Fix composer.json for incorrect order and whitespace",
"qa": "Run all quality assurance checks/tests",
"rector": "Check Rector rules without applying them",
"rector:fix": "Fix Rector rules",
"test": "Run all integration tests with PHPUnit",
"test:integration": "Run unit tests for Timber core",
"test:integration:acf": "Run unit tests related to the ACF integration for Timber",
Expand Down
1 change: 1 addition & 0 deletions grumphp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ grumphp:
composer_normalize: ~
ecs: ~
phplint: ~
rector: ~
# phpstan:
# memory_limit: "-1"
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ parameters:
- vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php
- vendor/php-stubs/acf-pro-stubs/acf-pro-stubs.php
excludePaths:
- rector.php
- tests/*
- docs/*
ignoreErrors:
Expand Down
24 changes: 24 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Php80\Rector\Class_\StringableForToStringRector;
use Rector\Php81\Rector\Array_\FirstClassCallableRector;

return RectorConfig::configure()
->withPaths([
__DIR__ . '/src',
])
->withPhpSets(
php81: true,
)
->withPreparedSets(
// deadCode: true,
// codeQuality: true,
// earlyReturn: true,
)
->withSkip([
FirstClassCallableRector::class,
StringableForToStringRector::class,
]);
4 changes: 2 additions & 2 deletions src/Archives.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public function items($args = null)
$limit = \absint($args['limit']);
$limit = ' LIMIT ' . $limit;
}
$order = \strtoupper($order);
$order = \strtoupper((string) $order);
if ($order !== 'ASC') {
$order = 'DESC';
}
Expand Down Expand Up @@ -372,7 +372,7 @@ public function items($args = null)
$text = $result->ID;
if ($result->post_title) {
/** This filter is documented in wp-includes/post-template.php */
$text = \strip_tags(\apply_filters('the_title', $result->post_title, $result->ID));
$text = \strip_tags((string) \apply_filters('the_title', $result->post_title, $result->ID));
}
$output[] = $this->get_archives_link($url, $text);
}
Expand Down
18 changes: 4 additions & 14 deletions src/Attachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class Attachment extends Post
*
* @var integer|null
*/
protected ?int $size;
protected ?int $size = null;

/**
* Gets the src for an attachment.
Expand Down Expand Up @@ -136,10 +136,7 @@ public function path(): string
*/
public function file(): string
{
if (isset($this->file)) {
return $this->file;
}
return $this->file = (string) \get_post_meta($this->ID, '_wp_attached_file', true);
return $this->file ?? ($this->file = (string) \get_post_meta($this->ID, '_wp_attached_file', true));
}

/**
Expand All @@ -151,10 +148,7 @@ public function file(): string
*/
public function file_loc(): string
{
if (isset($this->file_loc)) {
return $this->file_loc;
}
return $this->file_loc = (string) \get_attached_file($this->ID);
return $this->file_loc ?? ($this->file_loc = (string) \get_attached_file($this->ID));
}

/**
Expand Down Expand Up @@ -278,10 +272,7 @@ public function size(): ?int
*/
public function extension(): string
{
if (isset($this->file_extension)) {
return $this->file_extension;
}
return $this->file_extension = \pathinfo($this->file(), PATHINFO_EXTENSION);
return $this->file_extension ?? ($this->file_extension = \pathinfo($this->file(), PATHINFO_EXTENSION));
}

/**
Expand Down Expand Up @@ -340,7 +331,6 @@ public function pathinfo()
*
* This method is used to retrieve the attachment metadata only when it's needed.
*
* @param string|null $key
* @return array|string|int|null
*/
protected function metadata(?string $key = null)
Expand Down
5 changes: 2 additions & 3 deletions src/Cache/KeyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
class KeyGenerator
{
/**
* @param mixed $value
* @return string
*/
public function generateKey($value)
public function generateKey(mixed $value)
{
if (\is_a($value, 'Timber\Cache\TimberKeyGeneratorInterface')) {
return $value->_get_cache_key();
Expand All @@ -20,7 +19,7 @@ public function generateKey($value)

$key = \md5(\json_encode($value));
if (\is_object($value)) {
$key = \get_class($value) . ';' . $key;
$key = $value::class . ';' . $key;
}

// Replace any of the reserved characters.
Expand Down
15 changes: 4 additions & 11 deletions src/Cache/WPObjectCacheAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,10 @@

class WPObjectCacheAdapter
{
private $cache_group;

/**
* @var Loader
*/
private $timberloader;

public function __construct(Loader $timberloader, $cache_group = 'timber')
{
$this->cache_group = $cache_group;
$this->timberloader = $timberloader;
public function __construct(
private readonly Loader $timberloader,
private $cache_group = 'timber'
) {
}

public function fetch($key)
Expand Down
17 changes: 9 additions & 8 deletions src/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Timber;

use Stringable;
use WP_Comment;

/**
Expand Down Expand Up @@ -33,7 +34,7 @@
* <p class="comment-attribution">- Sullivan Ballou</p>
* ```
*/
class Comment extends CoreEntity
class Comment extends CoreEntity implements Stringable
{
/**
* The underlying WordPress Core object.
Expand All @@ -42,7 +43,7 @@
*
* @var WP_Comment|null
*/
protected ?WP_Comment $wp_object;
protected ?WP_Comment $wp_object = null;

public $object_type = 'comment';

Expand Down Expand Up @@ -134,7 +135,7 @@
*/
public static function build(WP_Comment $wp_comment): static
{
$comment = new static();

Check failure on line 138 in src/Comment.php

View workflow job for this annotation

GitHub Actions / PHP static analysis

Unsafe usage of new static().
$comment->import($wp_comment);
$comment->ID = $wp_comment->comment_ID;
$comment->id = $wp_comment->comment_ID;
Expand Down Expand Up @@ -278,7 +279,7 @@
*/
public function content()
{
return \trim(\apply_filters('comment_text', $this->comment_content));
return \trim((string) \apply_filters('comment_text', $this->comment_content));
}

/**
Expand Down Expand Up @@ -374,7 +375,7 @@
*/
public function date($date_format = '')
{
$df = $date_format ? $date_format : \get_option('date_format');
$df = $date_format ?: \get_option('date_format');
$the_date = (string) \mysql2date($df, $this->comment_date);
return \apply_filters('get_comment_date ', $the_date, $df);
}
Expand Down Expand Up @@ -403,7 +404,7 @@
*/
public function time($time_format = '')
{
$tf = $time_format ? $time_format : \get_option('time_format');
$tf = $time_format ?: \get_option('time_format');
$the_time = (string) \mysql2date($tf, $this->comment_date);
return \apply_filters('get_comment_time', $the_time, $tf);
}
Expand Down Expand Up @@ -576,7 +577,7 @@
*/
protected function avatar_default($default, $email, $size, $host)
{
if (\substr($default, 0, 1) == '/') {
if (\str_starts_with($default, '/')) {
$default = \home_url() . $default;
}

Expand All @@ -598,7 +599,7 @@
$default = '';
} elseif ('gravatar_default' == $default) {
$default = $host . '/avatar/?s=' . $size;
} elseif (empty($email) && !\preg_match('/^https?:\/\//', $default)) {
} elseif (empty($email) && !\preg_match('/^https?:\/\//', (string) $default)) {
$default = $host . '/avatar/?d=' . $default . '&amp;s=' . $size;
}
return $default;
Expand Down Expand Up @@ -631,6 +632,6 @@
$out
);

return \str_replace('&#038;', '&amp;', \esc_url($out));
return \str_replace('&#038;', '&amp;', (string) \esc_url($out));
}
}
9 changes: 4 additions & 5 deletions src/CommentThread.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@
*/
class CommentThread extends ArrayObject
{
public $post_id;

public $_orderby = '';

public $_order = 'ASC';
Expand All @@ -60,10 +58,11 @@ class CommentThread extends ArrayObject
* @param array|boolean $args Optional. An array of arguments or false if initialization
* should be skipped.
*/
public function __construct($post_id, $args = [])
{
public function __construct(
public $post_id,
$args = []
) {
parent::__construct();
$this->post_id = $post_id;
if ($args || \is_array($args)) {
$this->init($args);
}
Expand Down
7 changes: 2 additions & 5 deletions src/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ abstract class Core
*/
public function __isset($field)
{
if (isset($this->$field)) {
return $this->$field;
}
return false;
return isset($this->$field);
}

/**
Expand Down Expand Up @@ -165,7 +162,7 @@ public function import($info, $force = false, $only_declared_properties = false)
* @param string $key The key of the meta field to update.
* @param mixed $value The new value.
*/
public function update($key, $value)
public function update($key, mixed $value)
{
Helper::deprecated('Timber\Core::update()', 'update_metadata()', '2.0.0');
\update_metadata($this->object_type, $this->ID, $key, $value);
Expand Down
2 changes: 1 addition & 1 deletion src/DateTimeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static function time_ago($from, $to = null, $format_past = null, $format_
$format_future = \__('%s from now');
}

$to = $to ?? \time();
$to ??= \time();
$to = \is_numeric($to)
? new DateTimeImmutable('@' . $to, \wp_timezone())
: new DateTimeImmutable($to, \wp_timezone());
Expand Down