/**
  * Parses the $xmlContent into a Gadget class
  *
  * @param string $xmlContent
  */
 public function parse($xmlContent)
 {
     libxml_use_internal_errors(true);
     $doc = new DOMDocument();
     if (!$doc->loadXML($xmlContent, LIBXML_NOCDATA)) {
         throw new GadgetSpecException("Error parsing gadget xml:\n" . XmlError::getErrors($xmlContent));
     }
     //TODO: we could do a XSD schema validation here, but both the schema and most of the gadgets seem to have some form of schema
     // violatons, so it's not really practical yet (and slow)
     // $doc->schemaValidate('gadget.xsd');
     $gadget = new GadgetSpec();
     $gadget->checksum = md5($xmlContent);
     $this->parseModulePrefs($doc, $gadget);
     $this->parseUserPrefs($doc, $gadget);
     $this->parseViews($doc, $gadget);
     //TODO: parse pipelined data
     return $gadget;
 }
 /**
  * Parses the (remote / fetched) message bundle xml
  *
  * @param string $messageBundleData
  * @return array (MessageBundle)
  */
 protected function parseMessageBundle($messageBundleData)
 {
     libxml_use_internal_errors(true);
     $doc = new DOMDocument();
     if (!$doc->loadXML($messageBundleData, LIBXML_NOCDATA)) {
         throw new GadgetSpecException("Error parsing gadget xml:\n" . XmlError::getErrors($messageBundleData));
     }
     $messageBundle = array();
     if (($messageBundleNode = $doc->getElementsByTagName('messagebundle')) != null && $messageBundleNode->length > 0) {
         $messageBundleNode = $messageBundleNode->item(0);
         $messages = $messageBundleNode->getElementsByTagName('msg');
         foreach ($messages as $msg) {
             $messageBundle[$msg->getAttribute('name')] = trim($msg->nodeValue);
         }
     }
     return $messageBundle;
 }
 /**
  * Add a template library set, for details see:
  * http://opensocial-resources.googlecode.com/svn/spec/0.9/OpenSocial-Templating.xml#rfc.section.13
  *
  * @param string $library
  */
 public function addTemplateLibrary($library)
 {
     libxml_use_internal_errors(true);
     $doc = new DOMDocument(null, 'utf-8');
     $doc->preserveWhiteSpace = true;
     $doc->formatOutput = false;
     $doc->strictErrorChecking = false;
     $doc->recover = false;
     $doc->resolveExternals = false;
     if (!$doc->loadXML($library)) {
         throw new ExpressionException("Error parsing template library:\n" . XmlError::getErrors($library));
     }
     // Theoretically this could support multiple <Templates> root nodes, which isn't quite spec, but owell
     foreach ($doc->childNodes as $rootNode) {
         $templateNodes = array();
         $globalScript = array();
         $globalStyle = array();
         if (isset($rootNode->tagName) && $rootNode->tagName == 'Templates') {
             foreach ($rootNode->childNodes as $childNode) {
                 if (isset($childNode->tagName)) {
                     switch ($childNode->tagName) {
                         case 'TemplateDef':
                             $this->addTemplateDef($childNode, $globalScript, $globalStyle);
                             break;
                         case 'Template':
                             $templateNodes[] = $childNode;
                             break;
                         case 'JavaScript':
                             $globalScript[] = new TemplateLibraryContent($childNode->nodeValue);
                             break;
                         case 'Style':
                             $globalStyle[] = new TemplateLibraryContent($childNode->nodeValue);
                             break;
                     }
                 }
             }
         }
         // Initialize the templates after scanning the entire structure so that all scripts and styles will be included with each template
         foreach ($templateNodes as $templateNode) {
             $this->addTemplateByNode($templateNode, $globalScript, $globalStyle);
         }
     }
 }
 /**
  * Does the parsing of the template/data script content, then it hands
  * the os-data parsing to the DataPipeling class, and os-template tags to
  * the TemplateParser, and then returns the expanded template content (or '' on data)
  *
  * @param string $template
  * @param TemplateLibrary $templateLibrary
  * @return string
  */
 private function renderTemplate($template, TemplateLibrary $templateLibrary)
 {
     libxml_use_internal_errors(true);
     $this->doc = new DOMDocument(null, 'utf-8');
     $this->doc->preserveWhiteSpace = true;
     $this->doc->formatOutput = false;
     $this->doc->strictErrorChecking = false;
     $this->doc->recover = false;
     $this->doc->resolveExternals = false;
     if (!$this->doc->loadXML($template)) {
         return "Error parsing os-template:\n" . XmlError::getErrors($template);
     }
     if ($this->doc->childNodes->length < 1 || $this->doc->childNodes->length >> 1) {
         return 'Invalid script block';
     }
     $childNode = $this->doc->childNodes->item(0);
     if ($childNode->tagName == 'script' && $childNode->getAttribute('name') == null && $childNode->getAttribute('autoUpdate') != 'true') {
         // If the require tag is set, check to see if we have all required data parts, and if not leave it to the client to render
         if (($require = $childNode->getAttribute('require')) != null) {
             $requires = explode(',', $require);
             foreach ($requires as $val) {
                 $val = trim($val);
                 if (!isset($this->dataContext[$val])) {
                     return false;
                 }
             }
         }
         // if $childNode->tag exists, add to global $templateLibraries array, else parse normally
         $childNodeTag = $childNode->getAttribute('tag');
         if (!empty($childNodeTag)) {
             if (isset($this->templateLibraries[$childNode->getAttribute('tag')])) {
                 throw new ExpressionException("Template " . htmlentities($childNode->getAttribute('tag')) . " was already defined");
             }
             $templateLibrary->addTemplateByNode($childNode);
         } else {
             // Everything checked out, proceeding to render the template
             $parser = new TemplateParser();
             $parser->process($childNode, $this->dataContext, $templateLibrary);
             // unwrap the output, ie we only want the script block's content and not the main <script></script> node
             $output = new DOMDocument(null, 'utf-8');
             foreach ($childNode->childNodes as $node) {
                 $outNode = $output->importNode($node, true);
                 $outNode = $output->appendChild($outNode);
             }
             // Restore single tags to their html variant, and remove the xml header
             $ret = str_replace(array('<?xml version="" encoding="utf-8"?>', '<br/>', '<script type="text/javascript"><![CDATA[', ']]></script>'), array('', '<br>', '<script type="text/javascript">', '</script>'), $output->saveXML());
             return $ret;
         }
     }
     return false;
 }