3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
22 * The rewriter meta class, it checks the various gadget and configuration
23 * settings, and calls the appropiate classes for the registered dom element
26 class GadgetRewriter
{
28 private $domObservers = array();
30 public function __construct(GadgetContext
$context) {
31 $this->context
= $context;
35 * Does the actual rewrite option scanning and performs the dom parsing
37 * @param string $content
38 * @param Gadget $gadget
40 public function rewrite($content, Gadget
&$gadget) {
41 // Check to see if the gadget requested rewriting, or if rewriting is forced in the configuration
42 if (is_array($gadget->gadgetSpec
->rewrite
) || Config
::get('rewrite_by_default')) {
43 require_once "src/gadgets/rewrite/ContentRewriter.php";
44 $contentRewriter = new ContentRewriter($this->context
, $gadget);
45 $contentRewriter->register($this);
48 // Are we configured to sanitize certain views? (if so the config should be an array of view names to sanitize, iaw: array('profile', 'home'))
49 if (is_array(Config
::get('sanitize_views'))) {
50 require_once "src/gadgets/rewrite/SanitizeRewriter.php";
51 $sanitizeRewriter = new SanitizeRewriter($this->context
, $gadget);
52 $sanitizeRewriter->register($this);
55 // no observers registered, return the original content, otherwise parse the DOM tree and call the observers
56 if (!count($this->domObservers
)) {
59 libxml_use_internal_errors(true);
60 $doc = new DOMDocument(null, 'utf-8');
61 $doc->preserveWhiteSpace
= false;
62 $doc->formatOutput
= false;
63 $doc->strictErrorChecking
= false;
64 $doc->recover
= false;
65 if (! $doc->loadHtml($content)) {
66 // parsing failed, return the unmodified content
70 // find and parse all nodes in the dom document
71 $rootNodes = $doc->getElementsByTagName('*');
72 $this->parseNodes($rootNodes);
74 // DomDocument tries to make the document a valid html document, so added the html/body/head elements to it.. so lets strip them off before returning the content
75 $html = $doc->saveHTML();
76 $html = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace(array('&', '<head>', '</head>', '<html>', '</html>', '<body>', '</body>'), array('&', '', '', '', '', '', ''), $html));
78 // If the gadget specified the caja feature, cajole it
79 if (in_array('caja', $gadget->features
)) {
80 //TODO : use the caja daemon to cajole the content (experimental patch is available and will be added soon)
88 * This function should be called from the DomRewriter implmentation class in the form of:
89 * addObserver('img', $this, 'rewriteImage')
92 * @param object instance $class
93 * @param string $function
95 public function addObserver($tag, DomRewriter
$class, $function) {
96 // add the tag => function to call relationship to our $observers array
97 $this->domObservers
[] = array('tag' => $tag, 'class' => $class, 'function' => $function);
101 * Parses the DOMNodeList $nodes and calls the registered rewriting function on nodes
103 * @param DOMNodeList $nodes
105 private function parseNodes(DOMNodeList
&$nodes) {
106 foreach ($nodes as $node) {
107 $tagName = strtolower($node->tagName
);
108 foreach ($this->domObservers
as $observer) {
109 if ($observer['tag'] == $tagName) {
110 $class = $observer['class'];
111 $function = $observer['function'];
112 $class->$function($node);