ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Util.php
Go to the documentation of this file.
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
53define('XML_UTIL_ERROR_INVALID_CHARS', 51);
54
58define('XML_UTIL_ERROR_INVALID_START', 52);
59
63define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60);
64
68define('XML_UTIL_ERROR_NO_TAG_NAME', 61);
69
73define('XML_UTIL_REPLACE_ENTITIES', 1);
74
78define('XML_UTIL_CDATA_SECTION', 5);
79
83define('XML_UTIL_ENTITIES_NONE', 0);
84
89define('XML_UTIL_ENTITIES_XML', 1);
90
95define('XML_UTIL_ENTITIES_XML_REQUIRED', 2);
96
101define('XML_UTIL_ENTITIES_HTML', 3);
102
106define('XML_UTIL_COLLAPSE_ALL', 1);
107
111define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2);
112
126{
134 function apiVersion()
135 {
136 return '1.1';
137 }
138
179 function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
180 $encoding = 'ISO-8859-1')
181 {
182 switch ($replaceEntities) {
184 return strtr($string, array(
185 '&' => '&amp;',
186 '>' => '&gt;',
187 '<' => '&lt;',
188 '"' => '&quot;',
189 '\'' => '&apos;' ));
190 break;
192 return strtr($string, array(
193 '&' => '&amp;',
194 '<' => '&lt;',
195 '"' => '&quot;' ));
196 break;
198 return htmlentities($string, ENT_COMPAT, $encoding);
199 break;
200 }
201 return $string;
202 }
203
245 function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
246 $encoding = 'ISO-8859-1')
247 {
248 switch ($replaceEntities) {
250 return strtr($string, array(
251 '&amp;' => '&',
252 '&gt;' => '>',
253 '&lt;' => '<',
254 '&quot;' => '"',
255 '&apos;' => '\'' ));
256 break;
258 return strtr($string, array(
259 '&amp;' => '&',
260 '&lt;' => '<',
261 '&quot;' => '"' ));
262 break;
264 return html_entity_decode($string, ENT_COMPAT, $encoding);
265 break;
266 }
267 return $string;
268 }
269
289 function getXMLDeclaration($version = '1.0', $encoding = null,
290 $standalone = null)
291 {
292 $attributes = array(
293 'version' => $version,
294 );
295 // add encoding
296 if ($encoding !== null) {
297 $attributes['encoding'] = $encoding;
298 }
299 // add standalone, if specified
300 if ($standalone !== null) {
301 $attributes['standalone'] = $standalone ? 'yes' : 'no';
302 }
303
304 return sprintf('<?xml%s?>',
305 XML_Util::attributesToString($attributes, false));
306 }
307
328 function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
329 {
330 if (is_array($uri)) {
331 $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']);
332 } elseif (!empty($uri)) {
333 $ref = sprintf(' SYSTEM "%s"', $uri);
334 } else {
335 $ref = '';
336 }
337
338 if (empty($internalDtd)) {
339 return sprintf('<!DOCTYPE %s%s>', $root, $ref);
340 } else {
341 return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
342 }
343 }
344
383 function attributesToString($attributes, $sort = true, $multiline = false,
384 $indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML)
385 {
386 /*
387 * second parameter may be an array
388 */
389 if (is_array($sort)) {
390 if (isset($sort['multiline'])) {
391 $multiline = $sort['multiline'];
392 }
393 if (isset($sort['indent'])) {
394 $indent = $sort['indent'];
395 }
396 if (isset($sort['linebreak'])) {
397 $multiline = $sort['linebreak'];
398 }
399 if (isset($sort['entities'])) {
400 $entities = $sort['entities'];
401 }
402 if (isset($sort['sort'])) {
403 $sort = $sort['sort'];
404 } else {
405 $sort = true;
406 }
407 }
408 $string = '';
409 if (is_array($attributes) && !empty($attributes)) {
410 if ($sort) {
411 ksort($attributes);
412 }
413 if ( !$multiline || count($attributes) == 1) {
414 foreach ($attributes as $key => $value) {
415 if ($entities != XML_UTIL_ENTITIES_NONE) {
416 if ($entities === XML_UTIL_CDATA_SECTION) {
417 $entities = XML_UTIL_ENTITIES_XML;
418 }
419 $value = XML_Util::replaceEntities($value, $entities);
420 }
421 $string .= ' ' . $key . '="' . $value . '"';
422 }
423 } else {
424 $first = true;
425 foreach ($attributes as $key => $value) {
426 if ($entities != XML_UTIL_ENTITIES_NONE) {
427 $value = XML_Util::replaceEntities($value, $entities);
428 }
429 if ($first) {
430 $string .= ' ' . $key . '="' . $value . '"';
431 $first = false;
432 } else {
433 $string .= $linebreak . $indent . $key . '="' . $value . '"';
434 }
435 }
436 }
437 }
438 return $string;
439 }
440
455 {
456 if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) {
457 return preg_replace(
458 '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|'
459 . 'param)([^>]*)><\/\\1>/s',
460 '<\\1\\2 />',
461 $xml);
462 } else {
463 return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml);
464 }
465 }
466
504 function createTag($qname, $attributes = array(), $content = null,
505 $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
506 $multiline = false, $indent = '_auto', $linebreak = "\n",
507 $sortAttributes = true)
508 {
509 $tag = array(
510 'qname' => $qname,
511 'attributes' => $attributes
512 );
513
514 // add tag content
515 if ($content !== null) {
516 $tag['content'] = $content;
517 }
518
519 // add namespace Uri
520 if ($namespaceUri !== null) {
521 $tag['namespaceUri'] = $namespaceUri;
522 }
523
524 return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline,
525 $indent, $linebreak, $sortAttributes);
526 }
527
587 function createTagFromArray($tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
588 $multiline = false, $indent = '_auto', $linebreak = "\n",
589 $sortAttributes = true)
590 {
591 if (isset($tag['content']) && !is_scalar($tag['content'])) {
592 return XML_Util::raiseError('Supplied non-scalar value as tag content',
594 }
595
596 if (!isset($tag['qname']) && !isset($tag['localPart'])) {
597 return XML_Util::raiseError('You must either supply a qualified name '
598 . '(qname) or local tag name (localPart).',
600 }
601
602 // if no attributes hav been set, use empty attributes
603 if (!isset($tag['attributes']) || !is_array($tag['attributes'])) {
604 $tag['attributes'] = array();
605 }
606
607 if (isset($tag['namespaces'])) {
608 foreach ($tag['namespaces'] as $ns => $uri) {
609 $tag['attributes']['xmlns:' . $ns] = $uri;
610 }
611 }
612
613 if (!isset($tag['qname'])) {
614 // qualified name is not given
615
616 // check for namespace
617 if (isset($tag['namespace']) && !empty($tag['namespace'])) {
618 $tag['qname'] = $tag['namespace'] . ':' . $tag['localPart'];
619 } else {
620 $tag['qname'] = $tag['localPart'];
621 }
622 } elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) {
623 // namespace URI is set, but no namespace
624
625 $parts = XML_Util::splitQualifiedName($tag['qname']);
626
627 $tag['localPart'] = $parts['localPart'];
628 if (isset($parts['namespace'])) {
629 $tag['namespace'] = $parts['namespace'];
630 }
631 }
632
633 if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) {
634 // is a namespace given
635 if (isset($tag['namespace']) && !empty($tag['namespace'])) {
636 $tag['attributes']['xmlns:' . $tag['namespace']] =
637 $tag['namespaceUri'];
638 } else {
639 // define this Uri as the default namespace
640 $tag['attributes']['xmlns'] = $tag['namespaceUri'];
641 }
642 }
643
644 // check for multiline attributes
645 if ($multiline === true) {
646 if ($indent === '_auto') {
647 $indent = str_repeat(' ', (strlen($tag['qname'])+2));
648 }
649 }
650
651 // create attribute list
652 $attList = XML_Util::attributesToString($tag['attributes'],
653 $sortAttributes, $multiline, $indent, $linebreak, $replaceEntities);
654 if (!isset($tag['content']) || (string)$tag['content'] == '') {
655 $tag = sprintf('<%s%s />', $tag['qname'], $attList);
656 } else {
657 switch ($replaceEntities) {
659 break;
661 $tag['content'] = XML_Util::createCDataSection($tag['content']);
662 break;
663 default:
664 $tag['content'] = XML_Util::replaceEntities($tag['content'],
665 $replaceEntities);
666 break;
667 }
668 $tag = sprintf('<%s%s>%s</%s>', $tag['qname'], $attList, $tag['content'],
669 $tag['qname']);
670 }
671 return $tag;
672 }
673
700 function createStartElement($qname, $attributes = array(), $namespaceUri = null,
701 $multiline = false, $indent = '_auto', $linebreak = "\n",
702 $sortAttributes = true)
703 {
704 // if no attributes hav been set, use empty attributes
705 if (!isset($attributes) || !is_array($attributes)) {
706 $attributes = array();
707 }
708
709 if ($namespaceUri != null) {
710 $parts = XML_Util::splitQualifiedName($qname);
711 }
712
713 // check for multiline attributes
714 if ($multiline === true) {
715 if ($indent === '_auto') {
716 $indent = str_repeat(' ', (strlen($qname)+2));
717 }
718 }
719
720 if ($namespaceUri != null) {
721 // is a namespace given
722 if (isset($parts['namespace']) && !empty($parts['namespace'])) {
723 $attributes['xmlns:' . $parts['namespace']] = $namespaceUri;
724 } else {
725 // define this Uri as the default namespace
726 $attributes['xmlns'] = $namespaceUri;
727 }
728 }
729
730 // create attribute list
731 $attList = XML_Util::attributesToString($attributes, $sortAttributes,
732 $multiline, $indent, $linebreak);
733 $element = sprintf('<%s%s>', $qname, $attList);
734 return $element;
735 }
736
754 function createEndElement($qname)
755 {
756 $element = sprintf('</%s>', $qname);
757 return $element;
758 }
759
776 function createComment($content)
777 {
778 $comment = sprintf('<!-- %s -->', $content);
779 return $comment;
780 }
781
799 {
800 return sprintf('<![CDATA[%s]]>',
801 preg_replace('/\]\]>/', ']]]]><![CDATA[>', strval($data)));
802
803 }
804
829 function splitQualifiedName($qname, $defaultNs = null)
830 {
831 if (strstr($qname, ':')) {
832 $tmp = explode(':', $qname);
833 return array(
834 'namespace' => $tmp[0],
835 'localPart' => $tmp[1]
836 );
837 }
838 return array(
839 'namespace' => $defaultNs,
840 'localPart' => $qname
841 );
842 }
843
871 function isValidName($string)
872 {
873 // check for invalid chars
874 if (!preg_match('/^[[:alpha:]_]$/', $string{0})) {
875 return XML_Util::raiseError('XML names may only start with letter '
876 . 'or underscore', XML_UTIL_ERROR_INVALID_START);
877 }
878
879 // check for invalid chars
880 if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?$/',
881 $string)
882 ) {
883 return XML_Util::raiseError('XML names may only contain alphanumeric '
884 . 'chars, period, hyphen, colon and underscores',
886 }
887 // XML name is valid
888 return true;
889 }
890
905 function raiseError($msg, $code)
906 {
907 require_once 'PEAR.php';
908 return PEAR::raiseError($msg, $code);
909 }
910}
911?>
const XML_UTIL_ERROR_NON_SCALAR_CONTENT
error code for non-scalar tag content
Definition: Util.php:63
const XML_UTIL_ERROR_INVALID_CHARS
error code for invalid chars in XML name
Definition: Util.php:53
const XML_UTIL_ERROR_NO_TAG_NAME
error code for missing tag name
Definition: Util.php:68
const XML_UTIL_COLLAPSE_ALL
Collapse all empty tags.
Definition: Util.php:106
const XML_UTIL_COLLAPSE_XHTML_ONLY
Collapse only empty XHTML tags that have no end tag.
Definition: Util.php:111
const XML_UTIL_REPLACE_ENTITIES
replace XML entities
Definition: Util.php:73
const XML_UTIL_ENTITIES_XML
replace all XML entitites This setting will replace <, >, ", ' and &
Definition: Util.php:89
const XML_UTIL_ENTITIES_HTML
replace HTML entitites http://www.php.net/htmlentities
Definition: Util.php:101
const XML_UTIL_ENTITIES_XML_REQUIRED
replace only required XML entitites This setting will replace <, " and &
Definition: Util.php:95
const XML_UTIL_CDATA_SECTION
embedd content in a CData Section
Definition: Util.php:78
const XML_UTIL_ERROR_INVALID_START
error code for invalid chars in XML name
Definition: Util.php:58
const XML_UTIL_ENTITIES_NONE
do not replace entitites
Definition: Util.php:83
$comment
Definition: buildRTE.php:83
& raiseError($message=null, $code=null, $mode=null, $options=null, $userinfo=null, $error_class=null, $skipmsg=false)
This method is a wrapper that returns an instance of the configured error class with this object's de...
Definition: PEAR.php:524
createCDataSection($data)
create a CData section
Definition: Util.php:798
createStartElement($qname, $attributes=array(), $namespaceUri=null, $multiline=false, $indent='_auto', $linebreak="\n", $sortAttributes=true)
create a start element
Definition: Util.php:700
collapseEmptyTags($xml, $mode=XML_UTIL_COLLAPSE_ALL)
Collapses empty tags.
Definition: Util.php:454
createTagFromArray($tag, $replaceEntities=XML_UTIL_REPLACE_ENTITIES, $multiline=false, $indent='_auto', $linebreak="\n", $sortAttributes=true)
create a tag from an array this method awaits an array in the following format
Definition: Util.php:587
splitQualifiedName($qname, $defaultNs=null)
split qualified name and return namespace and local part
Definition: Util.php:829
getDocTypeDeclaration($root, $uri=null, $internalDtd=null)
build a document type declaration
Definition: Util.php:328
replaceEntities($string, $replaceEntities=XML_UTIL_ENTITIES_XML, $encoding='ISO-8859-1')
replace XML entities
Definition: Util.php:179
createComment($content)
create an XML comment
Definition: Util.php:776
reverseEntities($string, $replaceEntities=XML_UTIL_ENTITIES_XML, $encoding='ISO-8859-1')
reverse XML entities
Definition: Util.php:245
raiseError($msg, $code)
replacement for XML_Util::raiseError
Definition: Util.php:905
createEndElement($qname)
create an end element
Definition: Util.php:754
isValidName($string)
check, whether string is valid XML name
Definition: Util.php:871
attributesToString($attributes, $sort=true, $multiline=false, $indent=' ', $linebreak="\n", $entities=XML_UTIL_ENTITIES_XML)
create string representation of an attribute list
Definition: Util.php:383
getXMLDeclaration($version='1.0', $encoding=null, $standalone=null)
build an xml declaration
Definition: Util.php:289
apiVersion()
return API version
Definition: Util.php:134
createTag($qname, $attributes=array(), $content=null, $namespaceUri=null, $replaceEntities=XML_UTIL_REPLACE_ENTITIES, $multiline=false, $indent='_auto', $linebreak="\n", $sortAttributes=true)
create a tag
Definition: Util.php:504
$data
$code
Definition: example_050.php:99