Commit bd436f38 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Link: `alert` implemented.

OnArray.php: new explodeWithoutEscaped()
Link.php: new doQuestion()
Report.php: Link class will be initialized during __construct().
parent a51e1b9a
......@@ -188,6 +188,10 @@ const ERROR_DB_UNKNOWN_COLUMN = 2011;
const ERROR_DB_UNKNOWN_COMMAND = 2012;
const ERROR_DB_MISSING_COLUMN_ID = 2013;
const ERROR_DB_COLUMN_NOT_FOUND_IN_TABLE = 2014;
// onArray
const ERROR_SUBSTITUTE_FOUND = 2100;
//
// Store Names: Identifier
//
......@@ -442,4 +446,5 @@ const DB_INSERT_ID = 'insertId';
const COLUMN_CREATED = 'created';
const INDEX_PHP = 'index.php';
\ No newline at end of file
const INDEX_PHP = 'index.php';
......@@ -11,6 +11,8 @@ namespace qfq;
require_once(__DIR__ . '/../../qfq/Constants.php');
const SUBSTITUTE = '#%SUB%#';
/**
* Class OnArray
* @package qfq
......@@ -109,4 +111,30 @@ class OnArray {
}
return $arr;
}
/**
* Split Array around $str to $arr around $delimiter. Escaped $delimiter will be preserved.
*
* @param string $delimiter
* @param string $str
* @return array
* @throws UserReportException
*/
public static function explodeWithoutEscaped($delimiter, $str) {
if (strpos($str, SUBSTITUTE) !== false) {
throw new UserReportException ("Can't replace token by SUBSTITUTE, cause SUBSTITUTE already exist", ERROR_SUBSTITUTE_FOUND);
}
$encodedStr = str_replace('\\' . $delimiter, SUBSTITUTE, $str);
$arr = explode($delimiter, $encodedStr);
for ($ii = 0; $ii < count($arr); $ii++) {
$arr[$ii] = str_replace(SUBSTITUTE, '\\' . $delimiter, $arr[$ii]);
}
return $arr;
}
}
\ No newline at end of file
......@@ -83,8 +83,6 @@ const NAME_TARGET = 'target';
const NAME_LINK_CLASS = 'linkClass';
const NAME_LINK_CLASS_DEFAULT = 'linkClassDefault';
const NAME_QUESTION = 'question';
const NAME_QUESTION_TEXT = 'questionText';
const NAME_QUESTION_BUTTON = 'questionButton';
const NAME_ENCRYPTION = 'encryption';
const NAME_SIP = 'sip';
const NAME_URL_PARAM = 'param';
......@@ -134,7 +132,13 @@ const NO_CLASS = 'no_class';
const DEFAULT_BULLET_COLOR = 'green';
const DEFAULT_CHECK_COLOR = 'green';
const DEFAULT_RENDER_MODE = '0';
const DEFAULT_QUESTION_TEXT = 'Please confirm';
const DEFAULT_QUESTION_LEVEL = 'info';
const QUESTION_INDEX_TEXT = 0;
const QUESTION_INDEX_LEVEL = 1;
const QUESTION_INDEX_BUTTON_OK = 2;
const QUESTION_INDEX_BUTTON_FALSE = 3;
/**
* Class Link
......@@ -158,9 +162,15 @@ class Link {
// Simulate global variable: will be set much earlier in other functions. Will be shown in error messages.
private $fr_error;
/**
* @var bool
*/
private $phpUnit;
/**
* @var Utils
*/
private $utils;
/**
* @var array
......@@ -235,6 +245,7 @@ class Link {
* @param bool $phpUnit
*/
public function __construct($fr_error, Sip $sip, $phpUnit = false) {
$this->phpUnit = $phpUnit;
$this->fr_error = $fr_error;
$this->sip = $sip;
$this->store = Store::getInstance('', $phpUnit);
......@@ -377,7 +388,7 @@ class Link {
$vars = $this->initVars();
$flagArray = array();
// str="u:http://www.example.com|c:i|t:Hello World"
// str="u:http://www.example.com|c:i|t:Hello World|q:Do you really want to delete the record 25:warn:yes:no"
$param = explode("|", $str);
// Parse all parameter, fill variables
......@@ -456,8 +467,6 @@ class Link {
NAME_GLYPH => '',
NAME_GLYPH_TITLE => '',
NAME_QUESTION => '',
NAME_QUESTION_TEXT => 'Please confirm',
NAME_QUESTION_BUTTON => 'Ok',
NAME_TARGET => '',
NAME_TOOL_TIP => '',
NAME_TOOL_TIP_JS => '',
......@@ -508,6 +517,9 @@ class Link {
case TOKEN_SIP:
$value = '1';
break;
case TOKEN_QUESTION:
$value = DEFAULT_QUESTION_TEXT;
break;
case TOKEN_RENDER:
$value = DEFAULT_RENDER_MODE;
break;
......@@ -584,11 +596,12 @@ class Link {
*/
private function processParameter($vars) {
$vars[FINAL_HREF] = $this->doHref($vars); // must be called before tooltip
$vars[FINAL_HREF] = $this->doHref($vars); // must be called before doToolTip()
$vars[FINAL_TOOL_TIP] = $this->doToolTip($vars);
$vars[FINAL_CLASS] = $this->doCssClass($vars);
$vars[FINAL_SYMBOL] = $this->doSymbol($vars);
$vars[FINAL_CONTENT] = $this->doContent($vars);
$vars[FINAL_CONTENT] = $this->doContent($vars); // must be called after doSymbol()
$vars[FINAL_QUESTION] = $this->doQuestion($vars);
$vars[FINAL_ANCHOR] = $this->doAnchor($vars);
return $vars;
......@@ -736,6 +749,51 @@ class Link {
return $content;
}
/**
* Build 'alert' JS. $vars['question'] = '<text>:<color>:<button ok>:<button fail>'
* Return JS Code to place in '<a>' tag. Be carefull: function creates a uniqe 'id' tag.
*
* @param array $vars
* @return string
*/
private function doQuestion(array $vars) {
if ($vars[NAME_QUESTION] === '') {
return '';
}
$arr = OnArray::explodeWithoutEscaped(':', $vars[NAME_QUESTION]);
$arr = array_merge($arr, ['', '', '', '']);
$id = ($this->phpUnit === true) ? '12345' : uniqid('a_');
$content = Support::doAttribute('id', $id);
$text = $arr[QUESTION_INDEX_TEXT] === '' ? DEFAULT_QUESTION_TEXT : $arr[QUESTION_INDEX_TEXT];
$level = ($arr[QUESTION_INDEX_LEVEL] === '') ? DEFAULT_QUESTION_LEVEL : $arr[QUESTION_INDEX_LEVEL];
$ok = ($arr[QUESTION_INDEX_BUTTON_OK] === '') ? 'Ok' : $arr[QUESTION_INDEX_BUTTON_OK];
$cancel = ($arr[QUESTION_INDEX_BUTTON_FALSE] === '') ? 'Cancel' : $arr[QUESTION_INDEX_BUTTON_FALSE];
$js = <<<EOF
var alert = new QfqNS.Alert('$text', '$level', [
{ label: '$ok', eventName: 'ok' },
{ label: '$cancel',eventName: 'cancel'}
]);
alert.on('alert.ok', function() {
window.location = $('#$id').attr('href');
});
alert.show();
return false;
EOF;
$content .= Support::doAttribute('onClick', $js);
return $content;
}
/**
* Create the HTML anchor.
* - <a href="mailto:info@example.com" title=".." class="..">
......@@ -746,19 +804,17 @@ class Link {
* @throws UserReportException
*/
private function doAnchor(array $vars) {
$attributes = '';
$attributes .= Support::doAttribute('href', $vars[FINAL_HREF]);
$attributes .= Support::doAttribute('class', $vars[FINAL_CLASS]);
$attributes .= Support::doAttribute('target', $vars[NAME_TARGET]);
$attributes .= Support::doAttribute('title', $vars[FINAL_TOOL_TIP]);
if ($vars[NAME_QUESTION]) {
$attributes .= Support::doAttribute('onclick', 'confirm(\'' . $vars[NAME_QUESTION] . '\')');
}
$attributes .= $vars[FINAL_QUESTION];
$anchor = '<a ' . $attributes . '>';
return $anchor;
}
......
......@@ -46,6 +46,11 @@ class Report {
*/
private $sip = null;
/**
* @var Link
*/
private $link = null;
/**
* @var Store
*/
......@@ -126,6 +131,8 @@ class Report {
$this->sip->sipUniqId('badcaffee1234');
}
$this->link = new Link($this->fr_error, $this->sip, $phpUnit);
$this->store = Store::getInstance();
$this->showDebugInfo = ($this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) === 'yes');
......@@ -606,8 +613,7 @@ class Report {
//TODO: reserved names,not starting with '_' will be still accepted - stop this!
switch ($columnName) {
case "link":
$link = new Link($this->fr_error, $this->sip);
$content .= $link->renderLink($columnValue);
$content .= $this->link->renderLink($columnValue);
break;
case "exec":
......@@ -625,8 +631,7 @@ class Report {
$pageColumnName = strtolower($columnName);
$tokenizedValue = $this->doFixColPosPage($columnName, $columnValue);
$linkValue = $this->doPage($pageColumnName, $tokenizedValue);
$link = new Link($this->fr_error, $this->sip);
$content .= $link->renderLink($linkValue);
$content .= $this->link->renderLink($linkValue);
break;
case "page":
......@@ -638,8 +643,7 @@ class Report {
case "pagen":
case "pages":
$linkValue = $this->doPage($columnName, $columnValue);
$link = new Link($this->fr_error, $this->sip);
$content .= $link->renderLink($linkValue);
$content .= $this->link->renderLink($linkValue);
break;
case "bullet":
......@@ -648,8 +652,7 @@ class Report {
// r:3|B:
$linkValue = TOKEN_RENDER . ":3|" . TOKEN_BULLET . ":" . $columnValue;
$link = new Link($this->fr_error, $this->sip);
$content .= $link->renderLink($linkValue);
$content .= $this->link->renderLink($linkValue);
break;
case "check":
......@@ -658,8 +661,7 @@ class Report {
// "r:3|C:
$linkValue = TOKEN_RENDER . ":3|" . TOKEN_CHECK . ":" . $columnValue;
$link = new Link($this->fr_error, $this->sip);
$content .= $link->renderLink($linkValue);
$content .= $this->link->renderLink($linkValue);
break;
case "img":
......@@ -814,7 +816,7 @@ class Report {
*/
private function doFixColPosPage($columnName, $columnValue) {
$link = "";
$tokenList = "";
if (empty($columnName))
return '';
......@@ -830,45 +832,45 @@ class Report {
$firstParam[] = '';
}
$link .= $this->composeLinkPart(TOKEN_PAGE, $firstParam[0]); // -- PageID --
$link .= $this->composeLinkPart(TOKEN_URL_PARAM, $firstParam[1]);
$tokenList .= $this->composeLinkPart(TOKEN_PAGE, $firstParam[0]); // -- PageID --
$tokenList .= $this->composeLinkPart(TOKEN_URL_PARAM, $firstParam[1]);
if (isset($allParam[1]) && $allParam[1] !== '') {
$link .= $this->composeLinkPart(TOKEN_TEXT, $allParam[1]); // -- Text --
$tokenList .= $this->composeLinkPart(TOKEN_TEXT, $allParam[1]); // -- Text --
}
if (isset($allParam[2]) && $allParam[2] !== '') {
$link .= $this->composeLinkPart(TOKEN_TOOL_TIP, $allParam[2]); // -- tooltip --
$tokenList .= $this->composeLinkPart(TOKEN_TOOL_TIP, $allParam[2]); // -- tooltip --
}
if (isset($allParam[3]) && $allParam[3] !== '') {
$text = isset($this->pageDefaults["msgbox"][$columnName]) ? $this->pageDefaults["msgbox"][$columnName] : '';
$link .= $this->composeLinkPart(TOKEN_QUESTION, $allParam[3], $text); // -- msgbox
$tokenList .= $this->composeLinkPart(TOKEN_QUESTION, $allParam[3], $text); // -- msgbox
}
if (isset($allParam[4]) && $allParam[4] !== '') {
$link .= $this->composeLinkPart(TOKEN_CLASS, $allParam[4]); // -- class --
$tokenList .= $this->composeLinkPart(TOKEN_CLASS, $allParam[4]); // -- class --
}
if (isset($allParam[5]) && $allParam[5] !== '') {
$link .= $this->composeLinkPart(TOKEN_TARGET, $allParam[5]); // -- target --
$tokenList .= $this->composeLinkPart(TOKEN_TARGET, $allParam[5]); // -- target --
}
if (isset($allParam[6]) && $allParam[6] !== '') {
$link .= $this->composeLinkPart(TOKEN_RENDER, $allParam[6]); // -- render mode --
$tokenList .= $this->composeLinkPart(TOKEN_RENDER, $allParam[6]); // -- render mode --
}
if (!isset($allParam[7])) {
$allParam[7] = '1'; // if no SIP behaviour defined: sip is set
}
$link .= $this->composeLinkPart(TOKEN_SIP, $allParam[7]); // -- SIP --
$tokenList .= $this->composeLinkPart(TOKEN_SIP, $allParam[7]); // -- SIP --
if (isset($this->pageDefaults["icon"][$columnName])) {
$link .= $this->pageDefaults["icon"][$columnName] . "|";
$tokenList .= $this->pageDefaults["icon"][$columnName] . "|";
}
return ($link);
return ($tokenList);
}
/**
......
......@@ -756,11 +756,15 @@ class LinkTest extends \PHPUnit_Framework_TestCase {
$result = $link->renderLink('u:http://example.com|a:hello world|P:image.gif');
$this->assertEquals('<a href="http://example.com" ><img alt="hello world" src="image.gif" title="image.gif" ></a>', $result);
// standard: swapped parameter
//TODO: fixme
// $result = $link->renderLink('P:image.gif|a:hello world|u:http://example.com');
// $this->assertEquals('<a href="http://example.com" ><img alt="hello world" src="image.gif" title="image.gif" ></a>', $result);
// alt text empty
$result = $link->renderLink('u:http://example.com|a:|P:image.gif');
$this->assertEquals('<a href="http://example.com" ><img alt="image.gif" src="image.gif" title="image.gif" ></a>', $result);
// TODO: alttext has to be specified prior to 'P' - if not, there is an error generated. This should be fixed.
}
/**
......@@ -912,6 +916,51 @@ class LinkTest extends \PHPUnit_Framework_TestCase {
$link->renderLink('u:http://www.example.com|s:2');
}
/**
* @throws SyntaxReportException
*/
public function testQuestion() {
$link = new Link(null, $this->sip, true);
$js = <<<EOF
id="12345" onClick="var alert = new QfqNS.Alert('Please confirm', 'info', [
{ label: 'Ok', eventName: 'ok' },
{ label: 'Cancel',eventName: 'cancel'}
]);
alert.on('alert.ok', function() {
window.location = $('#12345').attr('href');
});
alert.show();
return false;"
EOF;
// Question
$result = $link->renderLink('p:person|c:n|q');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
// Question
$result = $link->renderLink('p:person|c:n|q:');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
$js = str_replace('Please confirm', 'do you really want', $js);
$result = $link->renderLink('p:person|c:n|q:do you really want');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
$js = str_replace('info', 'warn', $js);
$result = $link->renderLink('p:person|c:n|q:do you really want:warn');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
$js = str_replace('Ok', 'I do', $js);
$result = $link->renderLink('p:person|c:n|q:do you really want:warn:I do');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
$js = str_replace('Cancel', 'Shut up', $js);
$result = $link->renderLink('p:person|c:n|q:do you really want:warn:I do:Shut up');
$this->assertEquals('<a href="?id=person" ' . $js . ' >?id=person</a>', $result);
}
/**
......
......@@ -436,6 +436,20 @@ class ReportTest extends AbstractDatabaseTest {
*/
public function testReportPageFix() {
$js = <<<EOF
id="12345" onClick="var alert = new QfqNS.Alert('Please confirm', 'info', [
{ label: 'Ok', eventName: 'ok' },
{ label: 'Cancel',eventName: 'cancel'}
]);
alert.on('alert.ok', function() {
window.location = $('#12345').attr('href');
});
alert.show();
return false;"
EOF;
// _Page: only pagealias
$result = $this->report->process("10.sql = SELECT 'form' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="index.php?id=form&s=badcaffee1234" class="internal" >index.php?id=form&s=badcaffee1234</a>', $result);
......@@ -453,28 +467,30 @@ class ReportTest extends AbstractDatabaseTest {
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="internal" title="This is a tooltip" >Person</a>', $result);
// _Page: pagealias, param, Text, Tooltip, Question
// $result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question' AS _Page FROM Person ORDER BY id LIMIT 1");
// $this->assertEquals('', $result);
$js = str_replace('Please confirm', 'My Question', $js);
$result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="internal" title="This is a tooltip" ' . $js . ' >Person</a>', $result);
// _Page: pagealias, param, Text, Tooltip, Question, Class
// $result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question|myclass' AS _Page FROM Person ORDER BY id LIMIT 1");
// $this->assertEquals('', $result);
$result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question|myclass' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="myclass" title="This is a tooltip" ' . $js . ' >Person</a>', $result);
// _Page: pagealias, param, Text, Tooltip, Question, Class, Target
$result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question|myclass|mytarget' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="myclass" target="mytarget" title="This is a tooltip" onclick="confirm(\'My Question\')" >Person</a>', $result);
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="myclass" target="mytarget" title="This is a tooltip" ' . $js . ' >Person</a>', $result);
//TODO: implement
// _Page: pagealias, param, Text, Tooltip, Question, Class, Target, Rendermode
// $result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip|My Question|myclass|mytarget|0' AS _Page FROM Person ORDER BY id LIMIT 1");
// $this->assertEquals('', $result);
// _Page: pagealias, param, Text, Tooltip, Question, Class, Target, Rendermode, Sip ON 1
$result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip||myclass|mytarget|0|1' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="myclass" target="mytarget" title="This is a tooltip" >Person</a>', $result);
// $result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip||myclass|mytarget|0|1' AS _Page FROM Person ORDER BY id LIMIT 1");
// $this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="myclass" target="mytarget" title="This is a tooltip" ' . $js .' >Person</a>', $result);
// _Page: pagealias, param, Text, Tooltip, Question, Class, Target, Rendermode, Sip OFF
$result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip||myclass|mytarget|0|0' AS _Page FROM Person ORDER BY id LIMIT 1");
$this->assertEquals('<a href="?id=form&r=123&a=hello&type=5&L=3&final=world" class="myclass" target="mytarget" title="This is a tooltip" >Person</a>', $result);
// $result = $this->report->process("10.sql = SELECT 'form&r=123&a=hello&type=5&L=3&final=world|Person|This is a tooltip||myclass|mytarget|0|0' AS _Page FROM Person ORDER BY id LIMIT 1");
// $this->assertEquals('<a href="index.php?id=form&type=5&L=3&s=badcaffee1234" class="internal" title="This is a tooltip" ' . $js .' >Person</a>', $result);
}
......@@ -493,8 +509,6 @@ class ReportTest extends AbstractDatabaseTest {
}
/**
* @throws Exception
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment