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

Feature/t13547 tag enhancements #13566

Closed
wants to merge 4 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG-4.0.md
Expand Up @@ -11,7 +11,7 @@
- Added `forUpdate` in the Sqlite dialect to override the method from the base dialect. [#13539](https://github.com/phalcon/cphalcon/issues/13539)
- Added `TYPE_ENUM` in the Mysql adapter. [#11368](https://github.com/phalcon/cphalcon/issues/11368)
- Added `Phalcon\Acl\Adapter\Memory::addRole` support multiple inherited
- Refactored `Phalcon\Db\Adapter\Pdo::query` to use PDO's prepare and execute. `Phalcon\Db\Adapter::fetchAll` to use PDO's fetchAll
- Added `Phalcon\Tag::renderTitle()` that renders the title enclosed in `<title>` tags. [13547](https://github.com/phalcon/cphalcon/issues/13547)

## Changed
- By configuring `prefix` and `statsKey` the `Phalcon\Cache\Backend\Redis::queryKeys` no longer returns prefixed keys, now it returns original keys without prefix. [#13456](https://github.com/phalcon/cphalcon/pull/13456)
Expand All @@ -28,7 +28,9 @@
- Changed `Phalcon\Mvc\Model` to use the `Phalcon\Messages\Message` object for its messages [#13114](https://github.com/phalcon/cphalcon/issues/13114)
- Changed `Phalcon\Validation\*` to use the `Phalcon\Messages\Message` object for its messages [#13114](https://github.com/phalcon/cphalcon/issues/13114)
- Collections now use the Validation component [#12376](https://github.com/phalcon/cphalcon/pull/12376)
- Refactored `Phalcon\Db\Adapter\Pdo::query` to use PDO's prepare and execute. `Phalcon\Db\Adapter::fetchAll` to use PDO's fetchAll
- Fixed `\Phalcon\Http\Response::setFileToSend` filename last much _
- Changed `Phalcon\Tag::getTitle()`. It returns only the text. It accepts `prepend`, `append` booleans to prepend or append the relevant text to the title. [13547](https://github.com/phalcon/cphalcon/issues/13547)

## Removed
- PHP < 7.0 no longer supported
Expand Down
73 changes: 50 additions & 23 deletions phalcon/tag.zep
Expand Up @@ -1154,14 +1154,21 @@ class Tag
* The title will be automatically escaped.
*
* <code>
* echo Phalcon\Tag::getTitle();
* Tag::prependTitle('Hello');
* Tag::setTitle('World');
* Tag::appendTitle('from Phalcon');
*
* echo Tag::getTitle(); // Hello World from Phalcon
* echo Tag::getTitle(false); // World from Phalcon
* echo Tag::getTitle(true, false); // Hello World
* echo Tag::getTitle(false, false); // World
* </code>
*
* <code>
* {{ get_title() }}
* </code>
*/
public static function getTitle(boolean tags = true) -> string
public static function getTitle(boolean prepend = true, boolean append = true) -> string
{
var items, output, title, documentTitle, documentAppendTitle, documentPrependTitle, documentTitleSeparator, escaper;

Expand All @@ -1171,32 +1178,36 @@ class Tag
let documentTitle = escaper->escapeHtml(self::_documentTitle);
let documentTitleSeparator = escaper->escapeHtml(self::_documentTitleSeparator);

if typeof self::_documentAppendTitle == "null" {
let self::_documentAppendTitle = [];
}

let documentAppendTitle = self::_documentAppendTitle;

if typeof self::_documentPrependTitle == "null" {
let self::_documentPrependTitle = [];
}
if prepend {
if typeof self::_documentPrependTitle == "null" {
let self::_documentPrependTitle = [];
}

let documentPrependTitle = self::_documentPrependTitle;
let documentPrependTitle = self::_documentPrependTitle;

if !empty documentPrependTitle {
var tmp = array_reverse(documentPrependTitle);
for title in tmp {
let items[] = escaper->escapeHtml(title);
if !empty documentPrependTitle {
var tmp = array_reverse(documentPrependTitle);
for title in tmp {
let items[] = escaper->escapeHtml(title);
}
}
}

if !empty documentTitle {
let items[] = documentTitle;
}

if !empty documentAppendTitle {
for title in documentAppendTitle {
let items[] = escaper->escapeHtml(title);
if append {
if typeof self::_documentAppendTitle == "null" {
let self::_documentAppendTitle = [];
}

let documentAppendTitle = self::_documentAppendTitle;

if !empty documentAppendTitle {
for title in documentAppendTitle {
let items[] = escaper->escapeHtml(title);
}
}
}

Expand All @@ -1208,13 +1219,29 @@ class Tag
let output = implode(documentTitleSeparator, items);
}

if tags {
return "<title>" . output . "</title>" . PHP_EOL;
}

return output;
}

/**
* Renders the title with title tags. The title is automaticall escaped
*
* <code>
* Tag::prependTitle('Hello');
* Tag::setTitle('World');
* Tag::appendTitle('from Phalcon');
*
* echo Tag::renderTitle(); // <title>Hello World From Phalcon</title>
* </code>
*
* <code>
* {{ render_title() }}
* </code>
*/
public static function renderTitle() -> string
{
return "<title>" . self::getTitle() . "</title>" . PHP_EOL;
}

/**
* Gets the current document title separator
*
Expand Down
74 changes: 58 additions & 16 deletions tests/unit/Tag/TagTitleTest.php
Expand Up @@ -40,13 +40,33 @@ function () {
$value = "Hello </title><script>alert('Got your nose!');</script><title>";

Tag::setTitle($value);
$expected = "<title>Hello &lt;/title&gt;&lt;script&gt;alert(&#039;Got your nose!&#039;);&lt;/script&gt;&lt;title&gt;</title>" . PHP_EOL;
$expected = "Hello &lt;/title&gt;&lt;script&gt;alert(&#039;Got your nose!&#039;);&lt;/script&gt;&lt;title&gt;";

expect(Tag::getTitle())->equals($expected);
}
);
}

/**
* Tests malicious content in the title
* @since 2018-11-01
*/
public function testRenderTitleWithoutMaliciousContent()
{
$this->specify(
"getTitle returns malicious content",
function () {
Tag::resetInput();
$value = "Hello </title><script>alert('Got your nose!');</script><title>";

Tag::setTitle($value);
$expected = "<title>Hello &lt;/title&gt;&lt;script&gt;alert(&#039;Got your nose!&#039;);&lt;/script&gt;&lt;title&gt;</title>" . PHP_EOL;

expect(Tag::renderTitle())->equals($expected);
}
);
}

/**
* Tests setTitle
*
Expand All @@ -62,9 +82,9 @@ function () {
$value = 'This is my title';
Tag::setTitle($value);

expect(Tag::getTitle())->equals("<title>{$value}</title>" . PHP_EOL);
expect(Tag::renderTitle())->equals("<title>{$value}</title>" . PHP_EOL);

expect(Tag::getTitle(false))->equals("{$value}");
expect(Tag::getTitle())->equals("{$value}");
}
);
}
Expand All @@ -85,22 +105,28 @@ function () {
Tag::setTitle('Title');
Tag::appendTitle('Class');

expect(Tag::getTitle())->equals("<title>TitleClass</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Title");
expect(Tag::getTitle(false, true))->equals("TitleClass");
expect(Tag::renderTitle())->equals("<title>TitleClass</title>" . PHP_EOL);

Tag::resetInput();

Tag::setTitle('This is my title');
Tag::appendTitle(' - Welcome!');

expect(Tag::getTitle())->equals("<title>This is my title - Welcome!</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("This is my title");
expect(Tag::getTitle(false, true))->equals("This is my title - Welcome!");
expect(Tag::renderTitle())->equals("<title>This is my title - Welcome!</title>" . PHP_EOL);

Tag::resetInput();

Tag::setTitle('Title');
Tag::setTitleSeparator('|');
Tag::appendTitle('Class');

expect(Tag::getTitle())->equals("<title>Title|Class</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Title");
expect(Tag::getTitle(false, true))->equals("Title|Class");
expect(Tag::renderTitle())->equals("<title>Title|Class</title>" . PHP_EOL);

Tag::resetInput();

Expand All @@ -109,15 +135,19 @@ function () {
Tag::appendTitle('Category');
Tag::appendTitle('Title');

expect(Tag::getTitle())->equals("<title>Main - Category - Title</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(false, true))->equals("Main - Category - Title");
expect(Tag::renderTitle())->equals("<title>Main - Category - Title</title>" . PHP_EOL);

Tag::resetInput();

Tag::setTitle('Main');
Tag::setTitleSeparator(' - ');
Tag::appendTitle(['Category', 'Title']);

expect(Tag::getTitle())->equals("<title>Main - Category - Title</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(false, true))->equals("Main - Category - Title");
expect(Tag::renderTitle())->equals("<title>Main - Category - Title</title>" . PHP_EOL);

Tag::resetInput();

Expand All @@ -126,7 +156,9 @@ function () {
Tag::appendTitle('Category');
Tag::appendTitle([]);

expect(Tag::getTitle())->equals("<title>Main</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(false, true))->equals("Main");
expect(Tag::renderTitle())->equals("<title>Main</title>" . PHP_EOL);
}
);
}
Expand All @@ -148,15 +180,19 @@ function () {
Tag::setTitle('This is my title');
Tag::prependTitle('PhalconPHP - ');

expect(Tag::getTitle())->equals("<title>PhalconPHP - This is my title</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("This is my title");
expect(Tag::getTitle(true, false))->equals("PhalconPHP - This is my title");
expect(Tag::renderTitle())->equals("<title>PhalconPHP - This is my title</title>" . PHP_EOL);

Tag::resetInput();

Tag::setTitle('Title');
Tag::setTitleSeparator('|');
Tag::prependTitle('Class');

expect(Tag::getTitle())->equals('<title>Class|Title</title>' . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Title");
expect(Tag::getTitle(true, false))->equals("Class|Title");
expect(Tag::renderTitle())->equals("<title>Class|Title</title>" . PHP_EOL);

Tag::resetInput();

Expand All @@ -165,15 +201,19 @@ function () {
Tag::prependTitle('Category');
Tag::prependTitle('Title');

expect(Tag::getTitle())->equals("<title>Title - Category - Main</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(true, false))->equals("Title - Category - Main");
expect(Tag::renderTitle())->equals("<title>Title - Category - Main</title>" . PHP_EOL);

Tag::resetInput();

Tag::setTitle('Main');
Tag::setTitleSeparator(' - ');
Tag::prependTitle(['Category', 'Title']);

expect(Tag::getTitle())->equals("<title>Title - Category - Main</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(true, false))->equals("Title - Category - Main");
expect(Tag::renderTitle())->equals("<title>Title - Category - Main</title>" . PHP_EOL);

Tag::resetInput();

Expand All @@ -182,7 +222,9 @@ function () {
Tag::prependTitle('Category');
Tag::prependTitle([]);

expect(Tag::getTitle())->equals("<title>Main</title>" . PHP_EOL);
expect(Tag::getTitle(false, false))->equals("Main");
expect(Tag::getTitle(true, false))->equals("Main");
expect(Tag::renderTitle())->equals("<title>Main</title>" . PHP_EOL);
}
);
}
Expand Down Expand Up @@ -222,7 +264,7 @@ function () {
Tag::setTitleSeparator('-');
Tag::appendTitle('PhalconPHP');

expect(Tag::getTitle())->equals("<title>This is my title-PhalconPHP</title>" . PHP_EOL);
expect(Tag::renderTitle())->equals("<title>This is my title-PhalconPHP</title>" . PHP_EOL);
}
);
}
Expand All @@ -243,7 +285,7 @@ function () {
Tag::setTitleSeparator('-');
Tag::prependTitle('PhalconPHP');

expect(Tag::getTitle())->equals("<title>PhalconPHP-This is my title</title>" . PHP_EOL);
expect(Tag::renderTitle())->equals("<title>PhalconPHP-This is my title</title>" . PHP_EOL);
}
);
}
Expand Down