From 3d3590836ec3e25ca410dafeb37025f55804d716 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 16:37:52 -0500 Subject: [PATCH 01/16] Fix http url --- src/SimpleCalendar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SimpleCalendar.php b/src/SimpleCalendar.php index 7632c05..c77e405 100644 --- a/src/SimpleCalendar.php +++ b/src/SimpleCalendar.php @@ -6,7 +6,7 @@ * Simple Calendar * * @author Jesse G. Donat - * @see http://donatstudios.com + * @see https://donatstudios.com * @license http://opensource.org/licenses/mit-license.php */ class SimpleCalendar { From 65d0f43fb0f5b4a0c2b255787997e61fb13599e7 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 16:38:05 -0500 Subject: [PATCH 02/16] Min PHP 7.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 81a758e..15b5506 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "homepage" : "https://donatstudios.com/SimpleCalendar", "license" : "MIT", "require" : { - "php" : ">=5.5.0", + "php" : ">=7.2", "ext-calendar": "*" }, "require-dev": { From 62334469c3453a3cc383dd1611cb58dd0f17eff2 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 16:41:27 -0500 Subject: [PATCH 03/16] Remove unnecessary if --- src/SimpleCalendar.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/SimpleCalendar.php b/src/SimpleCalendar.php index c77e405..bdd957c 100644 --- a/src/SimpleCalendar.php +++ b/src/SimpleCalendar.php @@ -247,14 +247,10 @@ public function render() { $weekDayIndex = ($weekDayIndex + 7) % 7; - if( $weekDayIndex === 7 ) { - $weekDayIndex = 0; - } else { - $out .= str_repeat(<<  TAG - , $weekDayIndex); - } + , $weekDayIndex); $count = $weekDayIndex + 1; for( $i = 1; $i <= $daysInMonth; $i++ ) { From 8baa22dbc4909275b5b5ad0e34d4da5e1b2977be Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 16:41:37 -0500 Subject: [PATCH 04/16] Correct backwards annotation --- test/SimpleCalendarTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SimpleCalendarTest.php b/test/SimpleCalendarTest.php index efbe6f9..c17e5c1 100644 --- a/test/SimpleCalendarTest.php +++ b/test/SimpleCalendarTest.php @@ -240,7 +240,7 @@ private function parseCalendarHtml( SimpleCalendar $cal ) { $rowArray = []; foreach( $tr->childNodes as $childNode ) { /** - * @var $childNode \DOMElement + * @var \DOMElement $childNode */ $class = $childNode->getAttribute("class"); $rowItem = [ From 1a58af768e3298b569cc69752dd165e988cabb11 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:02:47 -0500 Subject: [PATCH 05/16] Cleans up composer.json some --- composer.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 15b5506..7ad0ef1 100644 --- a/composer.json +++ b/composer.json @@ -6,18 +6,20 @@ "homepage" : "https://donatstudios.com/SimpleCalendar", "license" : "MIT", "require" : { - "php" : ">=7.2", + "php": ">=7.2", "ext-calendar": "*" }, "require-dev": { - "phpunit/phpunit": "*", - "ext-dom": "*" + "ext-dom": "*", + "donatj/drop": "^1.1", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "*" }, "authors" : [ { "name" : "Jesse G. Donat", "email" : "donatj@gmail.com", - "homepage": "http://donatstudios.com", + "homepage": "https://donatstudios.com", "role" : "Developer" } ], @@ -25,5 +27,8 @@ "psr-4": { "donatj\\": "src/" } + }, + "config": { + "sort-packages": true } } From 604fee7415ac0c0236636214cf00052a69a80572 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:03:11 -0500 Subject: [PATCH 06/16] Add phpstan.neon --- phpstan.neon | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 phpstan.neon diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ef8e9f7 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 9 + paths: + - src + - test From aa9d9c95c1e53486012d67919862a071736bf492 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:03:23 -0500 Subject: [PATCH 07/16] Fixup --- src/SimpleCalendar.php | 46 +++++++++++++++++++++++++------------ test/SimpleCalendarTest.php | 39 ++++++++++++++++--------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/SimpleCalendar.php b/src/SimpleCalendar.php index bdd957c..f47b229 100644 --- a/src/SimpleCalendar.php +++ b/src/SimpleCalendar.php @@ -28,6 +28,9 @@ class SimpleCalendar { */ private $today; + /** + * @var array + */ private $classes = [ 'calendar' => 'SimpleCalendar', 'leading_day' => 'SCprefix', @@ -37,7 +40,11 @@ class SimpleCalendar { 'events' => 'events', ]; + /** + * @var array>>> + */ private $dailyHtml = []; + /** @var int */ private $offset = 0; /** @@ -58,7 +65,7 @@ public function __construct( $calendarDate = null, $today = null ) { * @param \DateTimeInterface|int|string|null $date DateTimeInterface or Date string parsed by strtotime for the * calendar date. If null set to current timestamp. */ - public function setDate( $date = null ) { + public function setDate( $date = null ) : void { $this->now = $this->parseDate($date) ?: new \DateTimeImmutable(); } @@ -66,7 +73,7 @@ public function setDate( $date = null ) { * @param \DateTimeInterface|int|string|null $date * @return \DateTimeInterface|null */ - private function parseDate( $date = null ) { + private function parseDate( $date = null ) : ?\DateTimeInterface { if( $date instanceof \DateTimeInterface ) { return $date; } @@ -94,9 +101,9 @@ private function parseDate( $date = null ) { * ] * ``` * - * @param array $classes Map of element to class names used by the calendar. + * @param array $classes Map of element to class names used by the calendar. */ - public function setCalendarClasses( array $classes ) { + public function setCalendarClasses( array $classes ) : void { foreach( $classes as $key => $value ) { if( !isset($this->classes[$key]) ) { throw new \InvalidArgumentException("class '{$key}' not supported"); @@ -109,10 +116,10 @@ public function setCalendarClasses( array $classes ) { /** * Sets "today"'s date. Defaults to today. * - * @param \DateTimeInterface|false|string|null $today `null` will default to today, `false` will disable the + * @param \DateTimeInterface|int|false|string|null $today `null` will default to today, `false` will disable the * rendering of Today. */ - public function setToday( $today = null ) { + public function setToday( $today = null ) : void { if( $today === false ) { $this->today = null; } elseif( $today === null ) { @@ -125,7 +132,7 @@ public function setToday( $today = null ) { /** * @param string[]|null $weekDayNames */ - public function setWeekDayNames( array $weekDayNames = null ) { + public function setWeekDayNames( array $weekDayNames = null ) : void { if( is_array($weekDayNames) && count($weekDayNames) !== 7 ) { throw new \InvalidArgumentException('week array must have exactly 7 values'); } @@ -140,7 +147,8 @@ public function setWeekDayNames( array $weekDayNames = null ) { * @param \DateTimeInterface|int|string $startDate Date string for when the event starts * @param \DateTimeInterface|int|string|null $endDate Date string for when the event ends. Defaults to start date */ - public function addDailyHtml( $html, $startDate, $endDate = null ) { + public function addDailyHtml( $html, $startDate, $endDate = null ) : void { + /** @var int $htmlCount */ static $htmlCount = 0; $start = $this->parseDate($startDate); @@ -175,25 +183,29 @@ public function addDailyHtml( $html, $startDate, $endDate = null ) { /** * Clear all daily events for the calendar */ - public function clearDailyHtml() { $this->dailyHtml = []; } + public function clearDailyHtml() : void { $this->dailyHtml = []; } /** * Sets the first day of the week * * @param int|string $offset Day the week starts on. ex: "Monday" or 0-6 where 0 is Sunday */ - public function setStartOfWeek( $offset ) { + public function setStartOfWeek( $offset ) : void { if( is_int($offset) ) { $this->offset = $offset % 7; } elseif( $this->weekDayNames !== null && ($weekOffset = array_search($offset, $this->weekDayNames, true)) !== false ) { + assert(is_int($weekOffset)); $this->offset = $weekOffset; } else { $weekTime = strtotime($offset); - if( $weekTime === 0 ) { + if( $weekTime === 0 || $weekTime === false ) { throw new \InvalidArgumentException('invalid offset'); } - $this->offset = date('N', $weekTime) % 7; + $date = date('N', $weekTime); + assert($date !== false); + + $this->offset = intval($date) % 7; } } @@ -228,7 +240,10 @@ public function render() { $daysOfWeek = $this->weekdays(); $this->rotate($daysOfWeek, $this->offset); - $weekDayIndex = date('N', mktime(0, 0, 1, $now['mon'], 1, $now['year'])) - $this->offset; + $time = mktime(0, 0, 1, $now['mon'], 1, $now['year']); + assert($time !== false); + + $weekDayIndex = date('N', $time) - $this->offset; $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $now['mon'], $now['year']); $out = << $data + * @param int $steps */ - private function rotate( array &$data, $steps ) { + private function rotate( array &$data, int $steps ) : void { $count = count($data); if( $steps < 0 ) { $steps = $count + $steps; diff --git a/test/SimpleCalendarTest.php b/test/SimpleCalendarTest.php index c17e5c1..16c51be 100644 --- a/test/SimpleCalendarTest.php +++ b/test/SimpleCalendarTest.php @@ -5,26 +5,27 @@ class SimpleCalendarTest extends TestCase { - public function testCurrentMonth() { + public function testCurrentMonth() : void { $cal = new SimpleCalendar(); self::assertNotFalse(strpos($cal->show(false), 'class="today"')); } - public function testBadDailyHtmlDates(){ + public function testBadDailyHtmlDates() : void { try { $cal = new SimpleCalendar('June 2010', 'June 5 2010'); $cal->addDailyHtml('foo', 'tomorrow', 'yesterday'); - } catch(InvalidArgumentException $ex) { + } catch( InvalidArgumentException $ex ) { self::assertTrue(true); + return; } self::fail('expected InvalidArgumentException'); } - public function testClasses() { - $cal = new SimpleCalendar('June 2010', 'June 5 2010'); + public function testClasses() : void { + $cal = new SimpleCalendar('June 2010', 'June 5 2010'); $defaults = [ 'SimpleCalendar', 'SCprefix', @@ -34,15 +35,15 @@ public function testClasses() { 'events', ]; - $cal->addDailyHtml( 'Sample Event', 'June 15 2010' ); + $cal->addDailyHtml('Sample Event', 'June 15 2010'); $cal_html = $cal->render(); foreach( $defaults as $class ) { self::assertNotFalse(strpos($cal_html, 'class="' . $class . '"')); } } - public function testCustomClasses() { - $cal = new SimpleCalendar('June 2010', 'June 5 2010'); + public function testCustomClasses() : void { + $cal = new SimpleCalendar('June 2010', 'June 5 2010'); $classes = [ 'calendar' => 'TestCalendar', 'leading_day' => 'TestPrefix', @@ -52,8 +53,8 @@ public function testCustomClasses() { 'events' => 'TestEvents', ]; - $cal->setCalendarClasses( $classes ); - $cal->addDailyHtml( 'Sample Event', 'June 15 2010' ); + $cal->setCalendarClasses($classes); + $cal->addDailyHtml('Sample Event', 'June 15 2010'); $cal_html = $cal->render(); foreach( $classes as $class ) { @@ -61,12 +62,12 @@ public function testCustomClasses() { } } - public function testCurrentMonth_yearRegression() { + public function testCurrentMonth_yearRegression() : void { $cal = new SimpleCalendar(sprintf('%d-%d-%d', (date('Y') - 1), date('n'), date('d'))); self::assertFalse(strpos($cal->show(false), 'class="today"')); } - public function testTagOpenCloseMismatch_regression() { + public function testTagOpenCloseMismatch_regression() : void { $cal = new SimpleCalendar(); $cal->setStartOfWeek(4); $cal->setDate('September 2016'); @@ -76,7 +77,7 @@ public function testTagOpenCloseMismatch_regression() { $this->assertSame(substr_count($html, 'setDate('January 2017'); $html = $cal->show(false); @@ -85,7 +86,7 @@ public function testTagOpenCloseMismatch_regression2() { $this->assertSame(substr_count($html, 'parseCalendarHtml($cal); @@ -155,7 +156,7 @@ public function testGenericGeneration() { $this->assertSame($expected, $tableArray); } - public function testGenericGeneration_mTs() { + public function testGenericGeneration_mTs() : void { $cal = new SimpleCalendar("June 5 2016"); $cal->setStartOfWeek(5); @@ -222,9 +223,9 @@ public function testGenericGeneration_mTs() { } /** - * @return array + * @return array>> */ - private function parseCalendarHtml( SimpleCalendar $cal ) { + private function parseCalendarHtml( SimpleCalendar $cal ) : array { $x = new DOMDocument(); @$x->loadHTML($cal->show(false)); @@ -259,7 +260,9 @@ private function parseCalendarHtml( SimpleCalendar $cal ) { $this->assertSame(0, $time->length); } else { $this->assertGreaterThan(0, $time->length); - $rowItem['date'] = $time->item(0)->getAttribute('datetime'); + $item = $time->item(0); + assert($item instanceof DOMElement); + $rowItem['date'] = $item->getAttribute('datetime'); } } From 99ebe7b248070ee47f9c7b3ad7e6ef88473fc154 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:10:41 -0500 Subject: [PATCH 08/16] Add phpcs and php-cs-fixer --- composer.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 7ad0ef1..4a1b9d9 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,12 @@ }, "require-dev": { "ext-dom": "*", + "corpus/coding-standard": "^0.8.0", "donatj/drop": "^1.1", + "friendsofphp/php-cs-fixer": "^3.37", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "*" + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "^3.7" }, "authors" : [ { @@ -29,6 +32,9 @@ } }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } From 7b6de7bf4a364e5c8c63be5a649fa2ee2cc6440b Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:11:48 -0500 Subject: [PATCH 09/16] Run fixer --- .gitignore | 1 + .php-cs-fixer.dist.php | 171 ++++++++++++++++++++++++++++++++++++ .php_cs | 117 ++++++++++++++++++++++++ example/basic.php | 2 +- phpcs.xml.dist | 12 +++ src/SimpleCalendar.php | 50 +++++------ test/SimpleCalendarTest.php | 22 ++--- 7 files changed, 337 insertions(+), 38 deletions(-) create mode 100644 .php-cs-fixer.dist.php create mode 100644 .php_cs create mode 100644 phpcs.xml.dist diff --git a/.gitignore b/.gitignore index bf3537a..1bac85b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor/ /composer.lock /clover.xml +*.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..a107aae --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,171 @@ +files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/test') + ->in(__DIR__ . '/example') + ->name('*.php'); + +return (new PhpCsFixer\Config) + ->setUsingCache(true) + ->setIndent("\t") + ->setLineEnding("\n") + //->setUsingLinter(false) + ->setRiskyAllowed(true) + ->setRules( + [ + '@PHPUnit60Migration:risky' => true, + 'php_unit_test_case_static_method_calls' => [ + 'call_type' => 'this', + ], + + 'concat_space' => [ + 'spacing' => 'one', + ], + + 'visibility_required' => true, + 'indentation_type' => true, + 'no_useless_return' => true, + + 'switch_case_space' => true, + 'switch_case_semicolon_to_colon' => true, + + 'array_syntax' => [ 'syntax' => 'short' ], + 'list_syntax' => [ 'syntax' => 'short' ], + + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + + 'no_whitespace_in_blank_line' => true, + + 'phpdoc_add_missing_param_annotation' => [ 'only_untyped' => true, ], + 'phpdoc_indent' => true, + + 'phpdoc_no_alias_tag' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + + 'phpdoc_var_annotation_correct_order' => true, + + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + + 'phpdoc_types' => true, + 'phpdoc_types_order' => [ + 'null_adjustment' => 'always_last', + 'sort_algorithm' => 'alpha', + ], + + 'phpdoc_align' => [ + 'align' => 'vertical', + 'tags' => [ 'param' ], + ], + + 'phpdoc_line_span' => [ + 'const' => 'single', + 'method' => 'multi', + 'property' => 'single', + ], + + 'short_scalar_cast' => true, + + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'no_spaces_after_function_name' => true, + 'no_unneeded_control_parentheses' => true, + + 'return_type_declaration' => [ + 'space_before' => 'one', + ], + + 'single_line_after_imports' => true, + 'single_blank_line_before_namespace' => true, + 'blank_line_after_namespace' => true, + 'single_blank_line_at_eof' => true, + 'ternary_to_null_coalescing' => true, + 'whitespace_after_comma_in_array' => true, + + 'cast_spaces' => [ 'space' => 'none' ], + + 'encoding' => true, + + 'space_after_semicolon' => [ + 'remove_in_empty_for_expressions' => true, + ], + + 'align_multiline_comment' => [ + 'comment_type' => 'phpdocs_like', + ], + + 'blank_line_before_statement' => [ + 'statements' => [ 'continue', 'try', 'switch', 'exit', 'throw', 'return', 'do' ], + ], + + 'no_superfluous_phpdoc_tags' => [ + 'remove_inheritdoc' => true, + ], + 'no_superfluous_elseif' => true, + + 'no_useless_else' => true, + + 'combine_consecutive_issets' => true, + 'escape_implicit_backslashes' => true, + 'explicit_indirect_variable' => true, + 'heredoc_to_nowdoc' => true, + + + 'no_singleline_whitespace_before_semicolons' => true, + 'no_null_property_initialization' => true, + 'no_whitespace_before_comma_in_array' => true, + + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_empty_comment' => true, + 'no_extra_blank_lines' => true, + 'no_blank_lines_after_phpdoc' => true, + + 'no_spaces_around_offset' => [ + 'positions' => [ 'outside' ], + ], + + 'return_assignment' => true, + 'lowercase_static_reference' => true, + + 'method_chaining_indentation' => true, + 'method_argument_space' => [ + 'on_multiline' => 'ignore', // at least until they fix it + 'keep_multiple_spaces_after_comma' => true, + ], + + 'multiline_comment_opening_closing' => true, + + 'include' => true, + 'elseif' => true, + + 'simple_to_complex_string_variable' => true, + + 'global_namespace_import' => [ + 'import_classes' => false, + 'import_constants' => false, + 'import_functions' => false, + ], + + 'trailing_comma_in_multiline' => true, + 'single_line_comment_style' => true, + + 'is_null' => true, + 'yoda_style' => [ + 'equal' => false, + 'identical' => false, + 'less_and_greater' => null, + ], + ] + ) + ->setFinder($finder); + + diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..548399d --- /dev/null +++ b/.php_cs @@ -0,0 +1,117 @@ +files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/test') + ->in(__DIR__ . '/example') + ->name('*.php'); + + +return PhpCsFixer\Config::create() + ->setUsingCache(true) + ->setIndent("\t") + ->setLineEnding("\n") + //->setUsingLinter(false) + //->setRiskyAllowed(true) + ->setRules( + [ + 'concat_space' => [ + 'spacing' => 'one', + ], + + 'visibility_required' => true, + 'indentation_type' => true, + 'no_useless_return' => true, + + 'switch_case_space' => true, + 'switch_case_semicolon_to_colon' => true, + + 'array_syntax' => [ 'syntax' => 'short' ], + 'list_syntax' => [ 'syntax' => 'short' ], + + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + + 'no_whitespace_in_blank_line' => true, + + 'phpdoc_add_missing_param_annotation' => [ 'only_untyped' => true, ], + 'phpdoc_indent' => true, + + 'phpdoc_no_alias_tag' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + + 'phpdoc_types' => true, + 'phpdoc_types_order' => [ + 'null_adjustment' => 'always_last', + 'sort_algorithm' => 'alpha', + ], + + 'short_scalar_cast' => true, + + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'no_spaces_after_function_name' => true, + 'no_unneeded_control_parentheses' => true, + + 'return_type_declaration' => [ + 'space_before' => 'one', + ], + + 'single_line_after_imports' => true, + 'single_blank_line_before_namespace' => true, + 'blank_line_after_namespace' => true, + 'single_blank_line_at_eof' => true, + 'ternary_to_null_coalescing' => true, + 'whitespace_after_comma_in_array' => true, + + 'cast_spaces' => [ 'space' => 'none' ], + + 'encoding' => true, + + 'space_after_semicolon' => [ + 'remove_in_empty_for_expressions' => true, + ], + + 'align_multiline_comment' => [ + 'comment_type' => 'phpdocs_like', + ], + + 'blank_line_before_statement' => [ + 'statements' => [ 'continue', 'try', 'switch', 'die', 'exit', 'throw', 'return' ], + ], + + 'no_superfluous_phpdoc_tags' => true, + 'no_superfluous_elseif' => true, + + 'no_useless_else' => true, + + 'combine_consecutive_issets' => true, + 'escape_implicit_backslashes' => true, + 'heredoc_to_nowdoc' => true, + + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_empty_comment' => true, + 'no_extra_blank_lines' => true, + 'no_blank_lines_after_phpdoc' => true, + + 'return_assignment' => true, + 'lowercase_static_reference' => true, + + 'method_chaining_indentation' => true, + + 'elseif' => true, + ] + ) + ->setFinder($finder); + + diff --git a/example/basic.php b/example/basic.php index bc02ed1..618971d 100644 --- a/example/basic.php +++ b/example/basic.php @@ -3,7 +3,7 @@ echo ''; -$calendar = new donatj\SimpleCalendar(); +$calendar = new donatj\SimpleCalendar; $calendar->setStartOfWeek('Sunday'); $calendar->addDailyHtml('Sample Event', 'today', 'tomorrow'); diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..3956e31 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,12 @@ + + + + src + test + example + + *.css + + + + diff --git a/src/SimpleCalendar.php b/src/SimpleCalendar.php index f47b229..fc08d21 100644 --- a/src/SimpleCalendar.php +++ b/src/SimpleCalendar.php @@ -18,19 +18,13 @@ class SimpleCalendar { */ private $weekDayNames; - /** - * @var \DateTimeInterface - */ + /** @var \DateTimeInterface */ private $now; - /** - * @var \DateTimeInterface|null - */ + /** @var \DateTimeInterface|null */ private $today; - /** - * @var array - */ + /** @var array */ private $classes = [ 'calendar' => 'SimpleCalendar', 'leading_day' => 'SCprefix', @@ -40,9 +34,7 @@ class SimpleCalendar { 'events' => 'events', ]; - /** - * @var array>>> - */ + /** @var array>>> */ private $dailyHtml = []; /** @var int */ private $offset = 0; @@ -63,23 +55,24 @@ public function __construct( $calendarDate = null, $today = null ) { * Sets the date for the calendar. * * @param \DateTimeInterface|int|string|null $date DateTimeInterface or Date string parsed by strtotime for the - * calendar date. If null set to current timestamp. + * calendar date. If null set to current timestamp. */ public function setDate( $date = null ) : void { - $this->now = $this->parseDate($date) ?: new \DateTimeImmutable(); + $this->now = $this->parseDate($date) ?: new \DateTimeImmutable; } /** * @param \DateTimeInterface|int|string|null $date - * @return \DateTimeInterface|null */ private function parseDate( $date = null ) : ?\DateTimeInterface { if( $date instanceof \DateTimeInterface ) { return $date; } + if( is_int($date) ) { - return (new \DateTimeImmutable())->setTimestamp($date); + return (new \DateTimeImmutable)->setTimestamp($date); } + if( is_string($date) ) { return new \DateTimeImmutable($date); } @@ -116,14 +109,14 @@ public function setCalendarClasses( array $classes ) : void { /** * Sets "today"'s date. Defaults to today. * - * @param \DateTimeInterface|int|false|string|null $today `null` will default to today, `false` will disable the - * rendering of Today. + * @param \DateTimeInterface|false|int|string|null $today `null` will default to today, `false` will disable the + * rendering of Today. */ public function setToday( $today = null ) : void { if( $today === false ) { $this->today = null; } elseif( $today === null ) { - $this->today = new \DateTimeImmutable(); + $this->today = new \DateTimeImmutable; } else { $this->today = $this->parseDate($today); } @@ -132,7 +125,7 @@ public function setToday( $today = null ) : void { /** * @param string[]|null $weekDayNames */ - public function setWeekDayNames( array $weekDayNames = null ) : void { + public function setWeekDayNames( ?array $weekDayNames = null ) : void { if( is_array($weekDayNames) && count($weekDayNames) !== 7 ) { throw new \InvalidArgumentException('week array must have exactly 7 values'); } @@ -143,9 +136,9 @@ public function setWeekDayNames( array $weekDayNames = null ) : void { /** * Add a daily event to the calendar * - * @param string $html The raw HTML to place on the calendar for this event + * @param string $html The raw HTML to place on the calendar for this event * @param \DateTimeInterface|int|string $startDate Date string for when the event starts - * @param \DateTimeInterface|int|string|null $endDate Date string for when the event ends. Defaults to start date + * @param \DateTimeInterface|int|string|null $endDate Date string for when the event ends. Defaults to start date */ public function addDailyHtml( $html, $startDate, $endDate = null ) : void { /** @var int $htmlCount */ @@ -160,6 +153,7 @@ public function addDailyHtml( $html, $startDate, $endDate = null ) : void { if( $endDate ) { $end = $this->parseDate($endDate); } + if( !$end ) { throw new \InvalidArgumentException('invalid end time'); } @@ -168,7 +162,8 @@ public function addDailyHtml( $html, $startDate, $endDate = null ) : void { throw new \InvalidArgumentException('end must come after start'); } - $working = (new \DateTimeImmutable())->setTimestamp($start->getTimestamp()); + $working = (new \DateTimeImmutable)->setTimestamp($start->getTimestamp()); + do { $tDate = getdate($working->getTimestamp()); @@ -183,7 +178,8 @@ public function addDailyHtml( $html, $startDate, $endDate = null ) : void { /** * Clear all daily events for the calendar */ - public function clearDailyHtml() : void { $this->dailyHtml = []; } + public function clearDailyHtml() : void { + $this->dailyHtml = []; } /** * Sets the first day of the week @@ -269,7 +265,7 @@ public function render() { $count = $weekDayIndex + 1; for( $i = 1; $i <= $daysInMonth; $i++ ) { - $date = (new \DateTimeImmutable())->setDate($now['year'], $now['mon'], $i); + $date = (new \DateTimeImmutable)->setDate($now['year'], $now['mon'], $i); $isToday = false; if( $this->today !== null ) { @@ -292,6 +288,7 @@ public function render() { foreach( $dailyHTML as $dHtml ) { $out .= sprintf('
%s
', $this->classes['event'], $dHtml); } + $out .= ''; } @@ -301,6 +298,7 @@ public function render() { $out .= "\n" . ($i < $daysInMonth ? '' : ''); $count = 0; } + $count++; } @@ -315,13 +313,13 @@ public function render() { /** * @param array $data - * @param int $steps */ private function rotate( array &$data, int $steps ) : void { $count = count($data); if( $steps < 0 ) { $steps = $count + $steps; } + $steps %= $count; for( $i = 0; $i < $steps; $i++ ) { $data[] = array_shift($data); diff --git a/test/SimpleCalendarTest.php b/test/SimpleCalendarTest.php index 16c51be..c87cd08 100644 --- a/test/SimpleCalendarTest.php +++ b/test/SimpleCalendarTest.php @@ -6,9 +6,9 @@ class SimpleCalendarTest extends TestCase { public function testCurrentMonth() : void { - $cal = new SimpleCalendar(); + $cal = new SimpleCalendar; - self::assertNotFalse(strpos($cal->show(false), 'class="today"')); + $this->assertNotFalse(strpos($cal->show(false), 'class="today"')); } public function testBadDailyHtmlDates() : void { @@ -16,12 +16,12 @@ public function testBadDailyHtmlDates() : void { $cal = new SimpleCalendar('June 2010', 'June 5 2010'); $cal->addDailyHtml('foo', 'tomorrow', 'yesterday'); } catch( InvalidArgumentException $ex ) { - self::assertTrue(true); + $this->assertTrue(true); return; } - self::fail('expected InvalidArgumentException'); + $this->fail('expected InvalidArgumentException'); } public function testClasses() : void { @@ -38,7 +38,7 @@ public function testClasses() : void { $cal->addDailyHtml('Sample Event', 'June 15 2010'); $cal_html = $cal->render(); foreach( $defaults as $class ) { - self::assertNotFalse(strpos($cal_html, 'class="' . $class . '"')); + $this->assertNotFalse(strpos($cal_html, 'class="' . $class . '"')); } } @@ -58,17 +58,17 @@ public function testCustomClasses() : void { $cal_html = $cal->render(); foreach( $classes as $class ) { - self::assertNotFalse(strpos($cal_html, 'class="' . $class . '"')); + $this->assertNotFalse(strpos($cal_html, 'class="' . $class . '"')); } } public function testCurrentMonth_yearRegression() : void { $cal = new SimpleCalendar(sprintf('%d-%d-%d', (date('Y') - 1), date('n'), date('d'))); - self::assertFalse(strpos($cal->show(false), 'class="today"')); + $this->assertFalse(strpos($cal->show(false), 'class="today"')); } public function testTagOpenCloseMismatch_regression() : void { - $cal = new SimpleCalendar(); + $cal = new SimpleCalendar; $cal->setStartOfWeek(4); $cal->setDate('September 2016'); $html = $cal->show(false); @@ -78,7 +78,7 @@ public function testTagOpenCloseMismatch_regression() : void { } public function testTagOpenCloseMismatch_regression2() : void { - $cal = new SimpleCalendar(); + $cal = new SimpleCalendar; $cal->setDate('January 2017'); $html = $cal->show(false); @@ -226,7 +226,7 @@ public function testGenericGeneration_mTs() : void { * @return array>> */ private function parseCalendarHtml( SimpleCalendar $cal ) : array { - $x = new DOMDocument(); + $x = new DOMDocument; @$x->loadHTML($cal->show(false)); $trs = $x->getElementsByTagName('tr'); @@ -234,7 +234,7 @@ private function parseCalendarHtml( SimpleCalendar $cal ) : array { $rowi = 0; foreach( $trs as $tr ) { /** - * @var $tr \DOMElement + * @var \DOMElement $tr */ $this->assertEquals(7, $tr->childNodes->length); From f828815ea5c8f3ca7a8b90e075269e9b9d0882fc Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:12:05 -0500 Subject: [PATCH 10/16] =?UTF-8?q?Drop=20pre-7.2=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e1586a..3150c4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] runs-on: ${{ matrix.operating-system }} From 8a5fc39e8c07031b0f1e8baae8dae03b8eb1cf0a Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:15:20 -0500 Subject: [PATCH 11/16] Minor fixup --- src/SimpleCalendar.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/SimpleCalendar.php b/src/SimpleCalendar.php index fc08d21..4a15f2d 100644 --- a/src/SimpleCalendar.php +++ b/src/SimpleCalendar.php @@ -56,6 +56,7 @@ public function __construct( $calendarDate = null, $today = null ) { * * @param \DateTimeInterface|int|string|null $date DateTimeInterface or Date string parsed by strtotime for the * calendar date. If null set to current timestamp. + * @throws \Exception */ public function setDate( $date = null ) : void { $this->now = $this->parseDate($date) ?: new \DateTimeImmutable; @@ -63,6 +64,7 @@ public function setDate( $date = null ) : void { /** * @param \DateTimeInterface|int|string|null $date + * @throws \Exception */ private function parseDate( $date = null ) : ?\DateTimeInterface { if( $date instanceof \DateTimeInterface ) { @@ -111,6 +113,7 @@ public function setCalendarClasses( array $classes ) : void { * * @param \DateTimeInterface|false|int|string|null $today `null` will default to today, `false` will disable the * rendering of Today. + * @throws \Exception */ public function setToday( $today = null ) : void { if( $today === false ) { @@ -139,8 +142,9 @@ public function setWeekDayNames( ?array $weekDayNames = null ) : void { * @param string $html The raw HTML to place on the calendar for this event * @param \DateTimeInterface|int|string $startDate Date string for when the event starts * @param \DateTimeInterface|int|string|null $endDate Date string for when the event ends. Defaults to start date + * @throws \Exception */ - public function addDailyHtml( $html, $startDate, $endDate = null ) : void { + public function addDailyHtml( string $html, $startDate, $endDate = null ) : void { /** @var int $htmlCount */ static $htmlCount = 0; @@ -179,7 +183,8 @@ public function addDailyHtml( $html, $startDate, $endDate = null ) : void { * Clear all daily events for the calendar */ public function clearDailyHtml() : void { - $this->dailyHtml = []; } + $this->dailyHtml = []; + } /** * Sets the first day of the week @@ -212,7 +217,7 @@ public function setStartOfWeek( $offset ) : void { * @return string HTML of the Calendar * @deprecated Use `render()` method instead. */ - public function show( $echo = true ) { + public function show( bool $echo = true ) : string { $out = $this->render(); if( $echo ) { echo $out; @@ -223,10 +228,8 @@ public function show( $echo = true ) { /** * Returns the generated Calendar - * - * @return string */ - public function render() { + public function render() : string { $now = getdate($this->now->getTimestamp()); $today = [ 'mday' => -1, 'mon' => -1, 'year' => -1 ]; if( $this->today !== null ) { @@ -329,7 +332,7 @@ private function rotate( array &$data, int $steps ) : void { /** * @return string[] */ - private function weekdays() { + private function weekdays() : array { if( $this->weekDayNames !== null ) { return $this->weekDayNames; } From 253b09474cbd3ad7cd4584cbfb0af199bd0d884a Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 17:16:39 -0500 Subject: [PATCH 12/16] Updates README --- .mddoc.xml | 2 +- README.md | 38 ++++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/.mddoc.xml b/.mddoc.xml index 700916c..4c9aa0d 100644 --- a/.mddoc.xml +++ b/.mddoc.xml @@ -20,7 +20,7 @@
- +
diff --git a/README.md b/README.md index 67ec939..bd7af18 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A very simple, easy to use PHP calendar rendering class. ## Requirements -- **php**: >=5.5.0 +- **php**: >=7.2 - **ext-calendar**: * ## Installing @@ -41,7 +41,7 @@ require '../vendor/autoload.php'; echo ''; -$calendar = new donatj\SimpleCalendar(); +$calendar = new donatj\SimpleCalendar; $calendar->setStartOfWeek('Sunday'); $calendar->addDailyHtml('Sample Event', 'today', 'tomorrow'); @@ -75,7 +75,7 @@ function __construct([ $calendarDate = null [, $today = null]]) #### Method: SimpleCalendar->setDate ```php -function setDate([ $date = null]) +function setDate([ $date = null]) : void ``` Sets the date for the calendar. @@ -85,12 +85,14 @@ Sets the date for the calendar. - ***\DateTimeInterface*** | ***int*** | ***string*** | ***null*** `$date` - DateTimeInterface or Date string parsed by strtotime for the calendar date. If null set to current timestamp. +**Throws**: `\Exception` + --- #### Method: SimpleCalendar->setCalendarClasses ```php -function setCalendarClasses(array $classes) +function setCalendarClasses(array $classes) : void ``` Sets the class names used in the calendar @@ -108,29 +110,31 @@ Sets the class names used in the calendar ##### Parameters: -- ***array*** `$classes` - Map of element to class names used by the calendar. +- ***array*** `$classes` - Map of element to class names used by the calendar. --- #### Method: SimpleCalendar->setToday ```php -function setToday([ $today = null]) +function setToday([ $today = null]) : void ``` Sets "today"'s date. Defaults to today. ##### Parameters: -- ***\DateTimeInterface*** | ***false*** | ***string*** | ***null*** `$today` - `null` will default to today, `false` will disable the +- ***\DateTimeInterface*** | ***false*** | ***int*** | ***string*** | ***null*** `$today` - `null` will default to today, `false` will disable the rendering of Today. +**Throws**: `\Exception` + --- #### Method: SimpleCalendar->setWeekDayNames ```php -function setWeekDayNames([ array $weekDayNames = null]) +function setWeekDayNames([ ?array $weekDayNames = null]) : void ``` ##### Parameters: @@ -142,7 +146,7 @@ function setWeekDayNames([ array $weekDayNames = null]) #### Method: SimpleCalendar->addDailyHtml ```php -function addDailyHtml($html, $startDate [, $endDate = null]) +function addDailyHtml(string $html, $startDate [, $endDate = null]) : void ``` Add a daily event to the calendar @@ -153,12 +157,14 @@ Add a daily event to the calendar - ***\DateTimeInterface*** | ***int*** | ***string*** `$startDate` - Date string for when the event starts - ***\DateTimeInterface*** | ***int*** | ***string*** | ***null*** `$endDate` - Date string for when the event ends. Defaults to start date +**Throws**: `\Exception` + --- #### Method: SimpleCalendar->clearDailyHtml ```php -function clearDailyHtml() +function clearDailyHtml() : void ``` Clear all daily events for the calendar @@ -168,7 +174,7 @@ Clear all daily events for the calendar #### Method: SimpleCalendar->setStartOfWeek ```php -function setStartOfWeek($offset) +function setStartOfWeek($offset) : void ``` Sets the first day of the week @@ -182,7 +188,7 @@ Sets the first day of the week #### Method: SimpleCalendar->show ```php -function show([ $echo = true]) +function show([ bool $echo = true]) : string ``` Returns/Outputs the Calendar @@ -204,11 +210,7 @@ Use `render()` method instead. #### Method: SimpleCalendar->render ```php -function render() +function render() : string ``` -Returns the generated Calendar - -##### Returns: - -- ***string*** \ No newline at end of file +Returns the generated Calendar \ No newline at end of file From 5bf45dfc43615fc772a94718ebafa8d4b8b928c0 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 22:49:31 -0500 Subject: [PATCH 13/16] Use correctly compatible versions --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4a1b9d9..0066b21 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ }, "require-dev": { "ext-dom": "*", - "corpus/coding-standard": "^0.8.0", + "corpus/coding-standard": "^0.6.0", "donatj/drop": "^1.1", - "friendsofphp/php-cs-fixer": "^3.37", + "friendsofphp/php-cs-fixer": "^3.3", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "*", "squizlabs/php_codesniffer": "^3.7" From 6920808718fa7cb79da26edb4f7422fbb45cb4a3 Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 22:51:42 -0500 Subject: [PATCH 14/16] Update autoloader syntax --- .mddoc.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.mddoc.xml b/.mddoc.xml index 4c9aa0d..9fbb7db 100644 --- a/.mddoc.xml +++ b/.mddoc.xml @@ -1,6 +1,7 @@ - + +
From 545572d8dc3fcacdbcb1483201ca6ad6c6de1c6e Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 22:51:59 -0500 Subject: [PATCH 15/16] Adds helpful Makefile --- Makefile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3535cec --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +SRC_FILES = $(shell find example src -type f -name '*.php') + +.PHONY: test +test: cs + vendor/bin/phpunit + vendor/bin/phpstan analyse --memory-limit 2g + +.PHONY: cs +cs: + vendor/bin/phpcs + +.PHONY: cbf +cbf: + vendor/bin/phpcbf + +.PHONY: fix +fix: cbf + vendor/bin/php-cs-fixer fix From 7baa58958e098814eb3270ad2cfd1467d7e03d5c Mon Sep 17 00:00:00 2001 From: Jesse Donat Date: Thu, 2 Nov 2023 22:52:16 -0500 Subject: [PATCH 16/16] Use Makefile --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3150c4c..3656d55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,5 +28,5 @@ jobs: - name: Install dependencies with composer run: composer install - - name: Test with phpunit - run: vendor/bin/phpunit + - name: Test + run: make test