static gboolean snippets_import_load_finished_lcb(gpointer data) { Tsnippets_import *si = (Tsnippets_import *)data; DEBUG_SIG("snippets_import_load_finished_lcb, priority=%d\n",G_PRIORITY_LOW); if (si->doc) { xmlNodePtr cur; cur = xmlDocGetRootElement(si->doc); if (cur) { if (xmlStrEqual(cur->name, (const xmlChar *) "snippets")) { xmlNodePtr newnode; /* now import everything below */ newnode = xmlDocCopyNodeList(snippets_v.doc, cur->children); xmlAddChildList(si->parent,newnode); reload_tree_from_doc(); g_idle_add(snippets_store_lcb, NULL); } } xmlFreeDoc(si->doc); } g_free(si->filename); g_free(si); return FALSE; }
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { xsltTransformContextPtr tctxt; zval *args; zval retval; int result, i; int error = 0; zend_fcall_info fci; zval handler; xmlXPathObjectPtr obj; char *str; xsl_object *intern; zend_string *callable = NULL; if (! zend_is_executing()) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { tctxt = xsltXPathGetTransformContext(ctxt); if (tctxt == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the transformation context\n"); error = 1; } else { intern = (xsl_object*)tctxt->_private; if (intern == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { args = safe_emalloc(fci.param_count, sizeof(zval), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(&args[i], (char *)obj->stringval); break; case XPATH_BOOLEAN: ZVAL_BOOL(&args[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(&args[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char*)xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } else if (type == 2) { int j; dom_object *domintern = (dom_object *)intern->doc; array_init(&args[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((char *)node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } else { node = xmlDocCopyNodeList(domintern->document->ptr, node); } php_dom_create_object(node, &child, domintern); add_next_index_zval(&args[i], &child); } } } break; default: str = (char *) xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } xmlXPathFreeObject(obj); } fci.size = sizeof(fci); fci.function_table = EG(function_table); if (fci.param_count > 0) { fci.params = args; } else { fci.params = NULL; } obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } return; } ZVAL_STRING(&handler, (char *) obj->stringval); xmlXPathFreeObject(obj); ZVAL_COPY_VALUE(&fci.function_name, &handler); fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.no_separation = 0; /*fci.function_handler_cache = &function_ptr;*/ if (!zend_make_callable(&handler, &callable)) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable)); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { result = zend_call_function(&fci, NULL); if (result == FAILURE) { if (Z_TYPE(handler) == IS_STRING) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */ } else if (Z_ISUNDEF(retval)) { } else { if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } Z_ADDREF(retval); zend_hash_next_index_insert(intern->node_list, &retval); obj = Z_DOMOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) { valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval))); } else if (Z_TYPE(retval) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { convert_to_string_ex(&retval); valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval))); } zval_ptr_dtor(&retval); } } zend_string_release(callable); zval_ptr_dtor(&handler); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } }
gchar* xhtml_extract (xmlNodePtr xml, gint xhtmlMode, const gchar *defaultBase) { xmlBufferPtr buf; xmlChar *xml_base = NULL; gchar *result = NULL; xmlNs *ns; /* Create the new document and add the div tag*/ xmlDocPtr newDoc = xmlNewDoc (BAD_CAST "1.0" ); xmlNodePtr divNode = xmlNewNode (NULL, BAD_CAST "div"); xmlDocSetRootElement (newDoc, divNode); xmlNewNs (divNode, BAD_CAST "http://www.w3.org/1999/xhtml", NULL); /* Set the xml:base of the div tag */ xml_base = xmlNodeGetBase (xml->doc, xml); if (xml_base) { xmlNodeSetBase (divNode, xml_base ); xmlFree (xml_base); } else if (defaultBase) xmlNodeSetBase (divNode, BAD_CAST defaultBase); if (xhtmlMode == 0) { /* Read escaped HTML and convert to XHTML, placing in a div tag */ xmlDocPtr oldDoc; xmlNodePtr copiedNodes = NULL; xmlChar *escapedhtml; /* Parse the HTML into oldDoc*/ escapedhtml = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); if (escapedhtml) { escapedhtml = BAD_CAST g_strstrip ((gchar*) escapedhtml); /* stripping whitespaces to make empty string detection easier */ if (*escapedhtml) { /* never process empty content, xmlDocCopy() doesn't like it... */ xmlNodePtr body; oldDoc = xhtml_parse ((gchar*) escapedhtml, strlen ((gchar*) escapedhtml)); body = xhtml_find_body (oldDoc); /* Copy namespace from original documents root node. This is ro determine additional namespaces for item content. For example to handle RSS 2.0 feeds as provided by LiveJournal: <rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'> <channel> ... <item> ... <description>... <span class='ljuser' lj:user='someone' style='white-space: nowrap;'><a href='http://community.livejournal.com/someone/profile'><img src='http://stat.livejournal.com/img/community.gif' alt='[info]' width='16' height='16' style='vertical-align: bottom; border: 0; padding-right: 2px;' /></a><a href='http://community.livejournal.com/someone/'><b>someone</b></a></span> ...</description> ... </item> ... </channel> Then we will want to extract <description> and need to honour the xmlns:lj definition... */ ns = (xmlDocGetRootElement (xml->doc))->nsDef; while (ns) { xmlNewNs (divNode, ns->href, ns->prefix); ns = ns->next; } if (body) { /* Copy in the html tags */ copiedNodes = xmlDocCopyNodeList (newDoc, body->xmlChildrenNode); // FIXME: is the above correct? Why only operate on the first child node? // It might be unproblematic because all content is wrapped in a <div>... xmlAddChildList (divNode, copiedNodes); } xmlFreeDoc (oldDoc); xmlFree (escapedhtml); } } } else if (xhtmlMode == 1 || xhtmlMode == 2) { /* Read multiple XHTML tags and embed in div tag */ xmlNodePtr copiedNodes = xmlDocCopyNodeList (newDoc, xml->xmlChildrenNode); xmlAddChildList (divNode, copiedNodes); } buf = xmlBufferCreate (); xmlNodeDump (buf, newDoc, xmlDocGetRootElement (newDoc), 0, 0 ); if (xmlBufferLength (buf) > 0) result = (gchar*) xmlCharStrdup ((gchar*) xmlBufferContent (buf)); xmlBufferFree (buf); xmlFreeDoc (newDoc); return result; }