] * B:bullet * c:class [n|i|e|] * C:checkbox [name] * d:download * D:delete * e:encryption 0|1 * E:edit * f: * F:File * g:target * G:Glyph * h: * H:Help * i:icon (Font Awesome, t) * I:information * j: * J: * k: * K: * l: * L: * m:mailto * M:Mode * n:GET/POST Rest Call * N:new * o:ToolTip * O:Monitor * p:page * P:picture [file] * q:question * Q: * r:render * R:right * s:sip * S:Show * t:text * T:Thumbnail * u:url * U:URL Param * v: * V: * w:websocket * W:Dimension * x:Delete * X: * y:Copy to clipboard * Y: * z:DropDown Menu * Z: * */ /** * Class Link * @package qfq */ class Link { /** * @var Sip */ private $sip = null; /** * @var Store */ private $store = null; /** * @var Thumbnail */ private $thumbnail = null; private $dbIndexData = false; private $phpUnit; private $renderControl = array(); // private $linkClassSelector = array(TOKEN_CLASS_INTERNAL => "internal ", TOKEN_CLASS_EXTERNAL => "external "); // private $cssLinkClassInternal = ''; // private $cssLinkClassExternal = ''; private $ttContentUid = ''; private $callTable = [ TOKEN_URL => 'buildUrl', TOKEN_MAIL => 'buildMail', TOKEN_PAGE => 'buildPage', TOKEN_COPY_TO_CLIPBOARD => 'buildCopyToClipboard', TOKEN_DOWNLOAD => 'buildDownload', TOKEN_DROPDOWN => 'buildDropdown', TOKEN_TOOL_TIP => 'buildToolTip', TOKEN_PICTURE => 'buildPicture', TOKEN_BULLET => 'buildBullet', TOKEN_CHECK => 'buildCheck', TOKEN_DELETE => 'buildDeleteIcon', TOKEN_ACTION_DELETE => 'buildActionDelete', TOKEN_EDIT => 'buildEdit', TOKEN_HELP => 'buildHelp', TOKEN_INFO => 'buildInfo', TOKEN_NEW => 'buildNew', TOKEN_SHOW => 'buildShow', TOKEN_FILE => 'buildFile', TOKEN_FILE_DEPRECATED => 'buildFile', TOKEN_GLYPH => 'buildGlyph', TOKEN_BOOTSTRAP_BUTTON => 'buildBootstrapButton', ]; private $tableVarName = [ TOKEN_URL => NAME_URL, TOKEN_MAIL => NAME_MAIL, TOKEN_PAGE => NAME_PAGE, TOKEN_UID => NAME_UID, TOKEN_SOURCE => NAME_SOURCE, TOKEN_DROPDOWN => NAME_DROPDOWN, TOKEN_DOWNLOAD => NAME_DOWNLOAD, TOKEN_DOWNLOAD_MODE => NAME_DOWNLOAD_MODE, TOKEN_TEXT => NAME_TEXT, TOKEN_ALT_TEXT => NAME_ALT_TEXT, TOKEN_BOOTSTRAP_BUTTON => NAME_BOOTSTRAP_BUTTON, TOKEN_TOOL_TIP => NAME_TOOL_TIP, TOKEN_PICTURE => NAME_IMAGE, TOKEN_BULLET => NAME_IMAGE, TOKEN_CHECK => NAME_IMAGE, TOKEN_DELETE => NAME_IMAGE, TOKEN_EDIT => NAME_IMAGE, TOKEN_HELP => NAME_IMAGE, TOKEN_INFO => NAME_IMAGE, TOKEN_NEW => NAME_IMAGE, TOKEN_SHOW => NAME_IMAGE, TOKEN_GLYPH => NAME_IMAGE, TOKEN_RENDER => NAME_RENDER, TOKEN_TARGET => NAME_TARGET, TOKEN_CLASS => NAME_LINK_CLASS, TOKEN_QUESTION => NAME_QUESTION, TOKEN_ENCRYPTION => NAME_ENCRYPTION, TOKEN_SIP => NAME_SIP, TOKEN_URL_PARAM => NAME_URL_PARAM, TOKEN_RIGHT => NAME_RIGHT, TOKEN_ACTION_DELETE => NAME_ACTION_DELETE, TOKEN_FILE => NAME_FILE, TOKEN_FILE_DEPRECATED => NAME_FILE, TOKEN_THUMBNAIL => NAME_THUMBNAIL, TOKEN_THUMBNAIL_DIMENSION => NAME_THUMBNAIL_DIMENSION, TOKEN_COPY_TO_CLIPBOARD => NAME_COPY_TO_CLIPBOARD, TOKEN_ATTRIBUTE => NAME_ATTRIBUTE, TOKEN_MONITOR => NAME_MONITOR, // The following don't need a renaming: already 'long' TOKEN_L_FILE => TOKEN_L_FILE, TOKEN_L_TAIL => TOKEN_L_TAIL, TOKEN_L_APPEND => TOKEN_L_APPEND, TOKEN_L_INTERVAL => TOKEN_L_INTERVAL, TOKEN_L_HTML_ID => TOKEN_L_HTML_ID, ]; // Used to find double definitions. private $tokenMapping = [ TOKEN_URL => LINK_ANCHOR, TOKEN_MAIL => LINK_ANCHOR, TOKEN_PAGE => LINK_ANCHOR, TOKEN_UID => LINK_ANCHOR, TOKEN_DOWNLOAD => LINK_ANCHOR, TOKEN_FILE => NAME_FILE, TOKEN_COPY_TO_CLIPBOARD => LINK_ANCHOR, TOKEN_PICTURE => LINK_PICTURE, TOKEN_BULLET => LINK_PICTURE, TOKEN_CHECK => LINK_PICTURE, TOKEN_DELETE => LINK_PICTURE, TOKEN_EDIT => LINK_PICTURE, TOKEN_HELP => LINK_PICTURE, TOKEN_INFO => LINK_PICTURE, TOKEN_NEW => LINK_PICTURE, TOKEN_SHOW => LINK_PICTURE, TOKEN_GLYPH => LINK_PICTURE, ]; /** * __construct * * @param Sip $sip * @param string $dbIndexData * @param bool $phpUnit * @throws \CodeException * @throws \UserFormException * @throws \UserReportException */ public function __construct(Sip $sip, $dbIndexData = DB_INDEX_DEFAULT, $phpUnit = false) { #TODO: rewrite $phpUnit to: "if (!defined('PHPUNIT_QFQ')) {...}" $this->phpUnit = $phpUnit; if ($phpUnit) { $_SERVER['REQUEST_URI'] = 'localhost'; } $this->sip = $sip; $this->store = Store::getInstance('', $phpUnit); // $this->cssLinkClassInternal = $this->store->getVar(SYSTEM_CSS_LINK_CLASS_INTERNAL, STORE_SYSTEM); // $this->cssLinkClassExternal = $this->store->getVar(SYSTEM_CSS_LINK_CLASS_EXTERNAL, STORE_SYSTEM); $this->ttContentUid = $this->store->getVar(TYPO3_TT_CONTENT_UID, STORE_TYPO3); $this->dbIndexData = $dbIndexData; /* * mode: * 0: no output * 1: text (no href) * 2: url (no href) * 3: url * 4: Text * 5: text * 6: url * 8: SIP only - 's=badcaffee1234' * * r=render mode, u=url, t:text and/or image. * * [r][u][t] = mode */ $this->renderControl[0][0][0] = 0; $this->renderControl[0][0][1] = 0; $this->renderControl[0][1][0] = 3; $this->renderControl[0][1][1] = 4; $this->renderControl[1][0][0] = 0; $this->renderControl[1][0][1] = 1; $this->renderControl[1][1][0] = 3; $this->renderControl[1][1][1] = 4; $this->renderControl[2][0][0] = 0; $this->renderControl[2][0][1] = 0; $this->renderControl[2][1][0] = 0; $this->renderControl[2][1][1] = 4; $this->renderControl[3][0][0] = 0; $this->renderControl[3][0][1] = 1; $this->renderControl[3][1][0] = 2; $this->renderControl[3][1][1] = 1; $this->renderControl[4][0][0] = 0; $this->renderControl[4][0][1] = 1; $this->renderControl[4][1][0] = 2; $this->renderControl[4][1][1] = 2; $this->renderControl[5][0][0] = 0; $this->renderControl[5][0][1] = 0; $this->renderControl[5][1][0] = 0; $this->renderControl[5][1][1] = 0; $this->renderControl[6][0][0] = 0; $this->renderControl[6][0][1] = 5; $this->renderControl[6][1][0] = 0; $this->renderControl[6][1][1] = 5; $this->renderControl[7][0][0] = 0; $this->renderControl[7][0][1] = 0; $this->renderControl[7][1][0] = 6; $this->renderControl[7][1][1] = 6; $this->renderControl[8][0][0] = 0; $this->renderControl[8][0][1] = 0; $this->renderControl[8][1][0] = 8; $this->renderControl[8][1][1] = 8; } /** * In render mode 3,4,5 there is no ''. Nevertheless, tooltip and BS Button should be displayed. * Do this by applying a '' attribute around the text. * * @param array $vars * @param $keyName * * @return mixed|string * @throws \CodeException */ private function wrapLinkTextOnly(array $vars, $keyName) { $text = $vars[$keyName]; if ($vars[NAME_BOOTSTRAP_BUTTON] == '' && $vars[FINAL_TOOL_TIP] == '' && $vars[NAME_ATTRIBUTE] == '') { return $text; } $attributes = Support::doAttribute('title', $vars[FINAL_TOOL_TIP]); if ($vars[NAME_ATTRIBUTE] != '') { $attributes .= $vars[NAME_ATTRIBUTE] . ' '; } if ($vars[NAME_BOOTSTRAP_BUTTON] != '') { $attributes .= Support::doAttribute('class', [$vars[NAME_BOOTSTRAP_BUTTON], 'disabled']); } return Support::wrapTag("", $text); } /** * Renders a (BS)-Dropdown menu. * * @param string $str * 'z|t:menu|b|o:click me' - the menu button to click on. A text 'menu', a BS button, a tooltip 'click me'. * '||p:detail&pId=1&s|t:Person 1' - Page id=detail with pId=1 will be opened in the browser. * '||d:file.pdf|p:detail&pId=1&_sip=1||t:Person as PDF' - Page id=detail with pId=1 will downloaded as a PDF. * * @param array $rcMenuEntryStrArr * @return string */ private function processDropdown($str, array &$rcMenuEntryStrArr) { $rcMenuEntryStrArr = array(); $tokenCollect = array(); // Split 'z|t:menu|b|o:click me||p:detail&pId=1&s|t:Person 1||...'. Add '||' to take care that the last element is flushed. $paramArr = KeyValueStringParser::explodeEscape(PARAM_DELIMITER, $str . '||'); // Iterate over token. Find delimiter to separate dropdown definition and all individual menu entries. foreach ($paramArr as $tokenStr) { $tokenArr = explode(PARAM_TOKEN_DELIMITER, $tokenStr, 2); switch ($tokenArr[0] ?? '') { // Indicator to start menu entry: force a flush of existing token and start a new round. case '': // New menu entry. if (!empty($tokenCollect)) { $rcMenuEntryStrArr[] = implode(PARAM_DELIMITER, $tokenCollect); } $tokenCollect = array(); break; default: $tokenCollect[] = $tokenStr; } } // First entry is the dropdown button, all others are the menu entries $dropdownButtonStr = array_shift($rcMenuEntryStrArr); return $dropdownButtonStr; } /** * https://getbootstrap.com/docs/3.4/components/#dropdowns * * Start * * * * * * *
* * *
* End * * @param array $menuEntryStrArr * @param $htmlId * @return string * @throws \CodeException * @throws \DbException * @throws \UserFormException * @throws \UserReportException */ private function renderDropdownUl(array $menuEntryStrArr, $htmlId) { $li = ''; foreach ($menuEntryStrArr as $str) { $attribute = ''; $link = $this->renderLink($str); switch (substr($link, 0, 3)) { case '---': $link = substr($link, 3); if ($link == '') { # Separator $attribute = ' role="separator" class="divider"'; } else { # Disabled $attribute = ' class="disabled"'; if (false === strstr($link, ''-tag, the 'disabled' class is broken - set a fake one. $link = Support::wrapTag('', $link); } } break; case '===': // Header $link = substr($link, 3); $attribute = ' class="dropdown-header"'; break; default: break; } // Menu entries $li .= '' . $link . ''; } // Wrapped Menu entries return Support::wrapTag('