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

Refactor word wrapping and on-node properties #817

Closed
wants to merge 9 commits into from
Closed
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
82 changes: 38 additions & 44 deletions src/Graph/GraphFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,54 +98,22 @@ public function buildGraph( $nodes ) {
/** @var GraphNode $node */
foreach ( $nodes as $node ) {
$instance = $this;
$nodeLabel = htmlspecialchars( $node->getLabel() );

// take "displaytitle" as node-label if it is set
if ( $this->options->getNodeLabel() === GraphPrinter::NODELABEL_DISPLAYTITLE ) {
if ( !empty( $nodeLabel ) ) {
$nodeLabel = $this->getWordWrappedText( $nodeLabel, $this->options->getWordWrapLimit() );
}
}

// URL.
$nodeLabel = $node->getLabel();
$nodeLinkURL = $this->options->isGraphLink() ? "[[" . $node->getID() . "]]" : null;
$nodeTooltip = null;

// Display fields, if any.
$fields = $node->getFields();
if ( count( $fields ) > 0 ) {
$label = $nodeLabel
?: strtr( $this->getWordWrappedText( $node->getID(), $this->options->getWordWrapLimit() ),
[ '\n' => '<br/>' ] );
$nodeTooltip = $nodeLabel ?: $node->getID();
// GraphViz is not working for version >= 1.33, so we need to use the Diagrams extension
// and formatting is a little different from the GraphViz extension
if ( version_compare( $wgVersion, '1.33', '>=' ) &&
\ExtensionRegistry::getInstance()->isLoaded( 'Diagrams' ) ) {
$nodeTooltip = str_replace( '<br />', '', $nodeTooltip );
}
// Label in HTML form enclosed with <>.
$nodeLabel = "<\n" . '<table border="0" cellborder="0" cellspacing="1" columns="*" rows="*">' . "\n"
. '<tr><td colspan="2" href="' . $nodeLinkURL . '">' . $label . "</td></tr><hr/>\n"
. implode( "\n", array_map( static function ( $field ) use ( $instance ) {
$alignment = in_array( $field['type'], [ '_num', '_qty', '_dat', '_tem' ] )
? 'right'
: 'left';
return '<tr><td align="left" href="[[Property:' . $field['page'] . ']]">'
. $field['name'] . '</td>'
. '<td align="' . $alignment . '">'
. $instance->getWordWrappedText(
$field['value'],
$instance->options->getWordWrapLimit()
)
. '</td></tr>';
}, $fields ) ) . "\n</table>\n>";
$label = $nodeLabel ?: $node->getID();
$nodeTooltip = $this->getWordWrappedText( htmlspecialchars( $label ) );
$nodeLabel = $this->getFieldsTable( $label, $nodeLinkURL, $fields );
$nodeLinkURL = null; // the value at the top is already hyperlinked.
} else {
if ( $nodeLabel ) {
// Label, if any, is enclosed with "".
$nodeLabel = '"' . htmlspecialchars( $nodeLabel ) . '"';
$nodeLabel = '"' . $this->getWordWrappedText( htmlspecialchars( $nodeLabel ) ) . '"';
}
$nodeTooltip = null;
}

/**
Expand All @@ -160,10 +128,10 @@ public function buildGraph( $nodes ) {
$inBrackets[] = 'URL = "' . $nodeLinkURL . '"';
}
if ( $nodeLabel ) {
$inBrackets[] = 'label = ' . $nodeLabel;
$inBrackets[] = 'label = ' . $nodeLabel; // already in quotes or <>.
}
if ( $nodeTooltip ) {
$inBrackets[] = 'tooltip = "' . htmlspecialchars( $nodeTooltip ) . '"';
$inBrackets[] = 'tooltip = "' . $nodeTooltip . '"';
}
if ( count( $inBrackets ) > 0 ) {
$this->add( ' [' . implode( ', ', $inBrackets ) . ']' );
Expand Down Expand Up @@ -225,6 +193,31 @@ public function buildGraph( $nodes ) {
$this->add( "}" );
}

/**
* Show node label and fields in an HTML table.
*
* @param string $label Node label,
* @param string $url Node URL,
* @param string[] $fields Node fields.
* @return string
*/
private function getFieldsTable( string $label, string $url, array $fields ): string {
$instance = $this;
// Label in HTML form enclosed with <>.
return "<\n" . '<table border="0" cellborder="0" cellspacing="1" columns="*" rows="*">' . "\n"
. '<tr><td colspan="2" href="' . $url . '">'
. $this->getWordWrappedText( htmlspecialchars( $label ), '<br />' )
. "</td></tr><hr/>\n"
. implode( "\n", array_map( static function ( $field ) use ( $instance ) {
$alignment = in_array( $field['type'], [ '_num', '_qty', '_dat', '_tem' ] ) ? 'right' : 'left';
return '<tr><td align="left" href="[[Property:' . $field['page'] . ']]">'
. $instance->getWordWrappedText( htmlspecialchars( $field['name'] ), '<br />' ) . '</td>'
. '<td align="' . $alignment . '">'
. $instance->getWordWrappedText( htmlspecialchars( $field['value'] ), '<br />' )
. '</td></tr>';
}, $fields ) ) . "\n</table>\n>";
}

/**
* Creates the graph legend
*
Expand Down Expand Up @@ -255,18 +248,19 @@ public function getGraphLegend() {
/**
* Returns the word wrapped version of the provided text.
*
* @param string $text
* @param int $charLimit
* @param string $text Text to word-wrap.
* @param ?string $br Override line separator.
*
* @return string
*/
public function getWordWrappedText( $text, $charLimit ) {
public function getWordWrappedText( string $text, ?string $br = null ): string {
$charLimit = $this->options->getWordWrapLimit();
preg_match_all(
'/\S{' . $charLimit . ',}|\S.{1,' . ( $charLimit - 1 ) . '}(?=\s+|$)/u',
$text,
$matches,
PREG_PATTERN_ORDER
);
return implode( $this->lineSeparator, $matches[0] );
return implode( $br ?? $this->lineSeparator, $matches[0] );
}
}
17 changes: 10 additions & 7 deletions tests/phpunit/Unit/Graph/GraphFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class GraphFormatterTest extends \PHPUnit\Framework\TestCase {
'graphlabel' => true,
'graphcolor' => true,
'graphlegend' => true,
'graphfields' => false,
];

/**
Expand All @@ -118,7 +119,7 @@ class GraphFormatterTest extends \PHPUnit\Framework\TestCase {
* @return GraphFormatter
*/
private static function graph( array $case ): GraphFormatter {
$graph = new GraphFormatter( new GraphOptions( GraphFormatterTest::BASE_PARAMS + $case['params'] ) );
$graph = new GraphFormatter( new GraphOptions( array_merge( GraphFormatterTest::BASE_PARAMS, $case['params'] ) ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason why you changed this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+ was an error. In this place $case['params'] should override GraphFormatterTest::BASE_PARAMS.

$nodes = [];
foreach ( $case['nodes'] as $node ) {
$graph_node = new GraphNode( $node['name'] );
Expand Down Expand Up @@ -151,7 +152,7 @@ public function provideCanConstruct(): array {
}

/**
* @covers GraphFormatter::__construct()
* @covers ::__construct()
* @dataProvider provideCanConstruct
* @param array $params
* @return void
Expand Down Expand Up @@ -181,17 +182,19 @@ public function provideGetWordWrappedText(): array {
}

/**
* @covers GraphFormatter::getWordWrappedText()
* @covers ::getWordWrappedText()
* @dataProvider provideGetWordWrappedText
* @param string $unwrapped
* @param string $wrapped
* @return void
*/
public function testGetWordWrappedText( $unwrapped, $wrapped ) {
$formatter = new GraphFormatter(
new GraphOptions( GraphFormatterTest::BASE_PARAMS + ['graphfields' => false] )
new GraphOptions( array_merge( GraphFormatterTest::BASE_PARAMS, [
'wordwraplimit' => 10
] ) )
);
$this->assertEquals( $wrapped, $formatter->getWordWrappedText( $unwrapped, 10 ) );
$this->assertEquals( $wrapped, $formatter->getWordWrappedText( $unwrapped ) );
}

/**
Expand All @@ -206,7 +209,7 @@ public function provideGetGraphLegend(): array {
}

/**
* @covers GraphFormatter::getGraphLegend()
* @covers ::getGraphLegend()
* @dataProvider provideGetGraphLegend
* @param array $params
* @param string $expected The expected legend.
Expand All @@ -228,7 +231,7 @@ public function provideBuildGraph(): array {
}

/**
* @covers GraphFormatter::buildGraph()
* @covers ::buildGraph()
* @dataProvider provideBuildGraph
* @param array $params
* @param string $expected The expected DOT code.
Expand Down
Loading