Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3cd7da4
Set up for unit tests, html code coverage report, AI-generated tests …
cviebrock Oct 3, 2025
fcda84f
Fix some phpstan level 1 issues
cviebrock Oct 3, 2025
1925ad4
Add clover reporting
cviebrock Oct 3, 2025
b15e8d9
Merge branch 'unit-tests' into phpstan-level-1-issues
cviebrock Oct 3, 2025
43deb59
Add unit tests to CI
cviebrock Oct 3, 2025
5bd0d90
Fix some issues and refactor SwatString::toList() (fixes counting ite…
cviebrock Oct 3, 2025
1fceeba
phpcs
cviebrock Oct 3, 2025
010505d
Reorganize directory structure/namespace for tests (HTML report still…
cviebrock Oct 3, 2025
5e5780d
Fix level 1 issues
cviebrock Oct 3, 2025
90a5bfc
Fix more level 1 issues
cviebrock Oct 3, 2025
5336520
Fix issue with SwatUIParent not being known
cviebrock Oct 6, 2025
282e8ba
When using named arguments, use them for all arguments
gauthierm Oct 6, 2025
24a15c0
Allow microseconds with setSeconds as per documentation
gauthierm Oct 6, 2025
b232d18
Clean up more types in input cell for row identifiers
gauthierm Oct 6, 2025
4eb3958
Move rounding to a protected method and make round results always ret…
gauthierm Oct 6, 2025
32a6d56
If no suitable input column is found, use td attributes of first column
gauthierm Oct 6, 2025
faa05a7
If there are no columns, do not display enter-another row
gauthierm Oct 6, 2025
34798b6
Pass an empty string as the title, as we do in other places for "non-…
cviebrock Oct 6, 2025
2d3240c
Merge pull request #2 from gauthierm/phpstan-level-1-issues
cviebrock Oct 6, 2025
8818ba9
Fix directory casing
cviebrock Oct 6, 2025
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
3 changes: 2 additions & 1 deletion .github/workflows/pull-requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
- name: Run tests
timeout-minutes: 5
run: |
pnpm prettier
composer run phpcs:ci
composer run phpstan:ci
composer run phpunit
pnpm prettier
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
vendor/
node_modules/

# testing and code styling output
/build/
.php-cs-fixer.cache
.phpunit.result.cache

# misc
.DS_Store
.env
.idea/
.php-cs-fixer.cache
*.swp

6 changes: 6 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ pipeline {
}
}

stage('Run Test Suite') {
steps {
sh 'composer run phpunit'
}
}

stage('Check Formating') {
steps {
sh 'n -d exec engine pnpm prettier'
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatByteCellRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SwatByteCellRenderer extends SwatCellRenderer
/**
* Value in bytes.
*
* @var float
* @var int
*/
public $value;

Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatCascadeFlydown.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ protected function &getOptions()
// if the options array doesn't exist for this parent_value, then
// assume that means we don't want any values in this flydown for
// that option.
$options = [new SwatOption(null, null)];
$options = [new SwatOption(null, '')];
}

return $options;
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatCellRendererSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public function getRendererByPosition($position = 0)
throw new SwatObjectNotFoundException(
'Set does not contain that many renderers.',
0,
$position,
(string) $position,
);
}

Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatCheckboxCellRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public function render()
echo '<span class="swat-checkbox-shim"></span>';
echo '</span>';

if ($this->title !== null) {
if (isset($label_tag)) {
$label_tag->displayContent();
$label_tag->close();
}
Expand Down
4 changes: 2 additions & 2 deletions Swat/SwatCheckboxTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ protected function validate(SwatDataTreeNode $node, $is_parent_selected)
: $is_parent_selected && !$is_selected;

return array_reduce(
$node->getChildren(),
iterator_to_array($node->getChildren()),
function ($carry, $child) use ($is_selected) {
return $carry && $this->validate($child, $is_selected);
},
Expand Down Expand Up @@ -269,7 +269,7 @@ private function displayNode(

// display children
$child_nodes = $node->getChildren();
if (count($child_nodes) > 0) {
if (iterator_count($child_nodes) > 0) {
echo '<ul>';
foreach ($child_nodes as $child_node) {
$nodes = $this->displayNode($child_node, $nodes, $index);
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ public function hasMessage()
* called elsewhere. To add a widget to a container use
* {@link SwatContainer::add()}.
*
* @param SwatWidget $child a reference to the child object to add
* @param SwatObject $child a reference to the child object to add
*
* @throws SwatInvalidClassException
*/
Expand Down
20 changes: 13 additions & 7 deletions Swat/SwatDate.php
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,6 @@ public static function getFormatLikeIntlById($id): string
*/
public static function getTimeZoneAbbreviations(): array
{
static $shortnames = null;

if (self::$tz_abbreviations === null) {
self::$tz_abbreviations = [];

Expand Down Expand Up @@ -737,10 +735,10 @@ public static function getTimeZoneAbbreviation(
$key = $time_zone->getName();

if (array_key_exists($key, $abbreviations)) {
$abbreviation = $abbreviations[$key];
return $abbreviations[$key];
}

return $abbreviation;
return [];
}

/**
Expand Down Expand Up @@ -905,7 +903,7 @@ public function getMinute(): int
*
* This method is provided for backwards compatibility with PEAR::Date.
*
* @return float the second of this date
* @return int the second of this date
*/
public function getSecond()
{
Expand Down Expand Up @@ -1143,7 +1141,7 @@ public function convertTZById($time_zone_name): DateTime
*/
public function setTZ(DateTimeZone $time_zone): DateTime
{
return $this->addSeconds($this->format('Z'))
return $this->addSeconds((float) $this->format('Z'))
->setTimezone($time_zone)
->subtractSeconds($this->format('Z'));
}
Expand Down Expand Up @@ -1482,7 +1480,15 @@ public function setMinute($minute): DateTime
*/
public function setSecond($second): DateTime
{
return $this->setTime($this->getHour(), $this->getMinute(), $second);
$whole_second = (int) $second;
$microsecond = (int) (abs($second - $whole_second) * 1_000_000);

return $this->setTime(
$this->getHour(),
$this->getMinute(),
$whole_second,
$microsecond
);
}

/**
Expand Down
14 changes: 5 additions & 9 deletions Swat/SwatDateEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ public function getState()
/**
* Sets the current state of this date entry widget.
*
* @param bool $state the new state of this date entry widget
* @param mixed $state the new state of this date entry widget
*
* @see SwatState::setState()
*/
Expand Down Expand Up @@ -530,11 +530,7 @@ protected function isStartDateValid()
{
$this->valid_range_start->setTZById('UTC');

return SwatDate::compare(
$this->value,
$this->valid_range_start,
true,
) >= 0;
return SwatDate::compare($this->value, $this->valid_range_start) >= 0;
}

/**
Expand All @@ -548,7 +544,7 @@ protected function isEndDateValid()
{
$this->valid_range_end->setTZById('UTC');

return SwatDate::compare($this->value, $this->valid_range_end, true)
return SwatDate::compare($this->value, $this->valid_range_end)
< 0;
}

Expand Down Expand Up @@ -720,7 +716,7 @@ protected function getMonthOptionText($month)
$text = '';

if ($this->show_month_number) {
$text .= str_pad($month, 2, '0', STR_PAD_LEFT) . ' - ';
$text .= sprintf('%02d', $month) . ' - ';
}

$date = new SwatDate('2010-' . $month . '-01');
Expand Down Expand Up @@ -764,7 +760,7 @@ protected function createDayFlydown()
for ($i = $start_day; $i <= $end_day; $i++) {
$flydown->addOption($i, $i);
}
} elseif (SwatDate::compare($end_check, $range_end, true) != -1) {
} elseif (SwatDate::compare($end_check, $range_end) != -1) {
// extra days at the beginning of the next month allowed
$days_in_month = $this->valid_range_start->getDaysInMonth();

Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ protected function getCSSClassNames()
protected function getNonce()
{
if ($this->nonce === null) {
$this->nonce = 'n' . md5(rand());
$this->nonce = 'n' . md5((string) rand());
}

return $this->nonce;
Expand Down
13 changes: 8 additions & 5 deletions Swat/SwatError.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ public function toString()
}

printf(
"%s. In file '%s' on line %s.\n%sMethod: %s%s%s(%s)\n",
str_pad(--$count, 6, ' ', STR_PAD_LEFT),
"%6d. In file '%s' on line %s.\n%sMethod: %s%s%s(%s)\n",
--$count,
array_key_exists('file', $entry) ? $entry['file'] : 'unknown',
array_key_exists('line', $entry) ? $entry['line'] : 'unknown',
str_repeat(' ', 8),
Expand Down Expand Up @@ -379,9 +379,12 @@ public function toXHTML()

if (array_key_exists('args', $entry)) {
$arguments = htmlspecialchars(
$this->getArguments($entry['args'], $function, $class),
null,
'UTF-8',
string: $this->getArguments(
$entry['args'],
$function,
$class
),
encoding: 'UTF-8',
);
} else {
$arguments = '';
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatGroupedFlydown.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected function displayNode(

if (
$level == 1
&& count($children) > 0
&& iterator_count($children) > 0
&& end($flydown_option->value) === null
&& !($flydown_option instanceof SwatFlydownDivider)
) {
Expand Down
8 changes: 4 additions & 4 deletions Swat/SwatHtmlHeadEntrySetDisplayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,13 @@ protected function getCombinedEntries(array $entries)
// add combines to set of entries
foreach ($info['combines'] as $combine) {
if (mb_substr($combine, -4) === '.css') {
$class_name = 'SwatStyleSheetHtmlHeadEntry';
$class_name = SwatStyleSheetHtmlHeadEntry::class;
} elseif (mb_substr($combine, -5) === '.less') {
$class_name = 'SwatLessStyleSheetHtmlHeadEntry';
$class_name = SwatLessStyleSheetHtmlHeadEntry::class;
} else {
$class_name = 'SwatJavaScriptHtmlHeadEntry';
$class_name = SwatJavaScriptHtmlHeadEntry::class;
}
$entries[$combine] = new $class_name($combine, '__combine__');
$entries[$combine] = new $class_name($combine);
}

// remove files included in combines
Expand Down
17 changes: 8 additions & 9 deletions Swat/SwatInputCell.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public function process($row_identifier)
* This creates a cloned widget for the given numeric identifier and then
* displays the widget.
*
* @param mixed $row_identifier
* @param int $row_identifier
*/
public function display($row_identifier)
{
Expand Down Expand Up @@ -228,9 +228,8 @@ public function getWidget($row_identifier, $widget_id = null)
*
* This is useful if you are deleting a row from an input row.
*
* @param int replicator_id the replicator id of the cloned widget to
* unset
* @param mixed $replicator_id
* @param int $replicator_id the replicator id of the cloned widget to
* unset
*
* @see SwatTableViewInputRow::removeReplicatedRow()
*/
Expand Down Expand Up @@ -469,11 +468,11 @@ protected function getInputRow()
/**
* Gets a cloned widget given a unique identifier.
*
* @param string $replicator_id the unique identifier of the new cloned
* widget. The actual cloned widget id is
* constructed from this identifier and from
* the input row that this input cell belongs
* to.
* @param int $replicator_id the unique identifier of the new cloned
* widget. The actual cloned widget id is
* constructed from this identifier and from
* the input row that this input cell belongs
* to.
*
* @return SwatWidget the new cloned widget or the cloned widget retrieved
* from the {@link SwatInputCell::$clones} array
Expand Down
9 changes: 5 additions & 4 deletions Swat/SwatNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,19 @@ public static function ordinal($value)

if (extension_loaded('intl')) {
// get current locale
$locale = setlocale(LC_ALL, 0);
$locale = setlocale(LC_ALL, '0');

static $formatters = [];
if (!isset($formatter[$locale])) {
$formatter[$locale] = new NumberFormatter(

if (!isset($formatters[$locale])) {
$formatters[$locale] = new NumberFormatter(
$locale,
NumberFormatter::ORDINAL,
);
}

// format ordinal
$ordinal_value = $formatter[$locale]->format($value);
$ordinal_value = $formatters[$locale]->format($value);

// decompose to latin-1 characters (removes superscripts)
$ordinal_value = Normalizer::normalize(
Expand Down
4 changes: 2 additions & 2 deletions Swat/SwatNumericEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function process()
$minimum_value = str_replace(
'%',
'%%',
$this->getDisplayValue($this->minimum_value),
$this->getDisplayValue((string) $this->minimum_value),
);

$message->primary_content = sprintf(
Expand All @@ -92,7 +92,7 @@ public function process()
$maximum_value = str_replace(
'%',
'%%',
$this->getDisplayValue($this->maximum_value),
$this->getDisplayValue((string) $this->maximum_value),
);

$message->primary_content = sprintf(
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatPercentageEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protected function getDisplayValue($value)
{
if (is_numeric($value)) {
$value = $value * 100;
$value = parent::getDisplayValue($value);
$value = parent::getDisplayValue((string) $value);
$value = $value . '%';
} else {
$value = parent::getDisplayValue($value);
Expand Down
2 changes: 1 addition & 1 deletion Swat/SwatRadioButtonCellRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function render()
echo '<span class="swat-radio-shim"></span>';
echo '</span>';

if ($this->title !== null) {
if (isset($label_tag)) {
$label_tag->displayContent();
$label_tag->close();
}
Expand Down
Loading