/** * */ public function testEscapeDefault() { $text = '<foo\\">\'&thing'; $ctx = new RenderContext(); $ctx->setLanguage(RenderContext::LANG_TEXT); RenderContext::push($ctx); $this->assertSame($text, String::escape($text), 'Escaping using RenderContext'); RenderContext::pop(); try { $tmp = String::escape($text, RenderContext::CONTENT_TEXT); $this->fail('Escape override failure did not fail.'); } catch (\InvalidArgumentException $e) { } }
/** * Adds a footnote to the page and returns a link to the footnote item. * * @param string $footnote The footnote text * @param boolean $escape Whether to escape the footnote content. * * @return string The rendered footnote link. */ public function add($footnote, $escape = false) { $this->footnotes[] = $escape ? String::escape($footnote) : $footnote; $index = count($this->footnotes); $attrs = array('class' => $this->class_link, 'href' => '#' . $this->fragment . $index, 'id' => $this->fragment . '-' . $index); return Tag::renderTag('a', $attrs, $index); }
/** * Render a custom block of HTML. * * @param string $error An error message to show, if applicable. * * @return string */ public function render($error = null) { $out = ''; if (isset($this['label'])) { $labelcontent = String::escape($this['label']) . ':'; if (isset($this['required']) && $this['required']) { $labelcontent .= ' <em>Required</em>'; } $out .= Tag::renderTag('label', array('for' => $this['id']), $labelcontent) . "\n"; } if (isset($this['content'])) { $content = $this['content']; } else { $content = ''; } if ($error) { $out .= self::renderError($this->props, $error); if (!isset($this->props['class'])) { $this->props['class'] = 'haserror'; } elseif (!preg_match('/(?:^| )haserror(?:$| )/', $this->props['class'])) { $this->props['class'] .= ' haserror'; } } $attrs = array_diff_key($this->props, array_flip(array('content', 'escape', 'name', 'type'))); $out .= Tag::renderTag('div', $attrs, $content) . "\n"; return $out; }
/** * Generate a list of records in the given table. * * If the given table is null, then all tables defined in the schema will be * listed. * * @param string $table The table from which records should be listed. * * @return string */ public function generateListPage($table) { ob_start(); if (is_null($table)) { // list all tables $this->outputPageHeader('All tables'); # $_GET[self::FORM_PREFIX.'_table'] echo "<ul>\n"; foreach (array_keys($this->schema) as $table) { echo '<li><a href="' . $this->generateActionUrl('list') . '&' . self::FORM_PREFIX . '_table=' . rawurlencode($table) . '">' . String::escape($table) . "</a></li>\n"; } echo "</ul>\n"; } else { // specific table $this->outputPageHeader('Table ' . $table); $db = $this->db; $primary_field = $this->schema[$table]['_primary']; // join with belongsTo tables (and hasMany?) if (count($this->schema[$table]['_belongsTo'])) { $sql = 'SELECT * FROM `' . $table . '` ORDER BY `' . $primary_field . '`'; $select = array(); $from = array(''); # critical hack to include one LEFT JOIN foreach (array_keys($this->schema[$table]['fields']) as $field) { if (isset($this->schema[$table]['_belongsTo'][$field])) { $linked_table = $this->schema[$table]['_belongsTo'][$field]; if (isset($this->schema[$linked_table]['_primary'])) { $linked_field = $this->schema[$linked_table]['_primary']; $linked_display_field = $this->schema[$linked_table]['_primary']; if (isset($this->schema[$linked_table]['_display'])) { $linked_display_field = $this->schema[$linked_table]['_display']; } $select[] = 'CONCAT(`' . $linked_table . '`.`' . $linked_display_field . '`, \' [\', `' . $table . '`.`' . $field . '`, \']\') AS `' . $field . '`'; $from[] = '`' . $linked_table . '` ON `' . $linked_table . '`.`' . $linked_field . '` = `' . $table . '`.`' . $field . '`'; } else { $select[] = '`' . $table . '`.`' . $field . '`'; } } else { $select[] = '`' . $table . '`.`' . $field . '`'; } } $sql = 'SELECT ' . implode(', ', $select) . ' FROM `' . $table . '`' . implode(' LEFT JOIN ', $from) . ' ORDER BY `' . $table . '`.`' . $primary_field . '`'; } else { $sql = 'SELECT * FROM `' . $table . '` ORDER BY `' . $primary_field . '`'; } $stmt = $db->prepare($sql); $stmt->execute(); if ($stmt->rowCount()) { $header = false; echo "<table class=\"scaffold\">\n<thead>\n<tr>"; $row = $stmt->fetch(\PDO::FETCH_ASSOC); foreach (array_keys($row) as $col) { echo '<th>' . String::escapeHTML($col) . '</th>'; } echo '<th class="actions">Actions</th>'; echo "</tr>\n</thead>\n<tfoot></tfoot>\n<tbody>\n"; $i = 0; do { echo '<tr class="zebra' . $i++ % 2 . '">'; foreach ($row as $k => $v) { if ($k === $primary_field) { echo '<td class="primary">' . String::escapeHTML($v) . '</td>'; } else { echo '<td>' . String::escapeHTML($v) . '</td>'; } } echo '<td class="actions"><a href="' . $this->generateActionUrl('update', $row[$primary_field]) . '">Edit</a> <a href="' . $this->generateActionUrl('delete', $row[$primary_field]) . '">Delete</a></th>'; echo "</tr>\n"; } while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)); echo "</tbody>\n</table>\n"; } else { echo '<p>No rows to display.</p>', "\n"; } echo '<p><a href="' . $this->generateActionUrl('create') . '">New item</a></p>', "\n"; } $this->outputPageFooter(); return ob_get_clean(); }
/** * Renders a tag according the the current render context. * * Note that content is <b>never</b> escaped. Specifying <tt>false</tt> for the content will force * an object tag in XML-based languages. An object tag will also always be generated for XHTML tags * which cannot contain content. * * @param string $tag The tag to render. * @param array $attrs An associative array of additional attributes. * @param string $content The inline content. * * @return string */ public static function renderTag($tag, array $attrs = array(), $content = null) { $tag = strtolower($tag); # Check for and warn about deprecated elements and attributes. if (Debug::isEnabled()) { self::checkDeprecatedElements($tag); self::checkDeprecatedAttributes($tag, array_keys($attrs)); } # Check whether we need to account for XML. $ctx = RenderContext::get(); $is_xml = $ctx->isXMLSyntax(); $r = '<' . $tag; foreach ($attrs as $k => $v) { if ($v === false || $k[0] === '_') { // attributes which should never be output continue; } if ($v === true) { // handle checked="checked", etc $v = $k; } $r .= ' ' . strtolower($k) . '="' . String::escape($v) . '"'; } if ($is_xml && ($content === false || self::isAlwaysEmpty($tag))) { $r .= ' />'; } else { $r .= '>'; } if (!is_null($content) && $content !== false) { if ($content !== '') { if (self::shouldMaskContent($tag)) { $r .= PHP_EOL . self::getContentMask($tag, true) . PHP_EOL; } $r .= $content; if (self::shouldMaskContent($tag)) { $r .= PHP_EOL . self::getContentMask($tag, false) . PHP_EOL; } } $r .= '</' . $tag . '>'; } return $r; }