Giter Club home page Giter Club logo

Comments (17)

veewee avatar veewee commented on August 30, 2024 2

That sure is possible by creating your own custom assembler that contains the code-geberation for this specific type of setter. You might want to place it after the regular FluentSetterAssembler and remove the set method if it already exist.

As a base, you could start by copying this class and alter it to your needs:
https://github.com/phpro/soap-client/blob/master/src/Phpro/SoapClient/CodeGenerator/Assembler/FluentSetterAssembler.php

You might also need to create a code generation rule that matches on both a TYPE name and a PROPERTY name. Unless you want to apply it on any "Description" property.

from ext-soap-engine.

veewee avatar veewee commented on August 30, 2024 1

That's also an option.
You could even add the <![CDATA[ ]]> part and check to conditionally run htmlentities based on that as well.

At least now you have an idea on how to tackle the issue :)

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024 1

That´s exactly what makes this framework so powerful ❤️ 😊

from ext-soap-engine.

veewee avatar veewee commented on August 30, 2024

Hello,

The easiest way forward is to add a Type converter:
https://github.com/php-soap/ext-soap-engine#typeconverter

The problem here, is that the Description element is a regular xsd:string element. It would have been nicer if it were a separate XSD type that could be overwritten.

You can fiddle around with this version a bit in your codebase to see how it behaves.
I tested it from my side and should work OK on basic data - assuming all other HTML fields expect CDATA as well.

<?php

use Soap\ExtSoapEngine\Configuration\TypeConverter\TypeConverterInterface;
use VeeWee\Xml\Dom\Document;

class CDataHtmlStringConverter implements TypeConverterInterface {
    public function getTypeNamespace(): string
    {
        return 'http://www.w3.org/2001/XMLSchema';
    }

    public function getTypeName(): string
    {
        return 'string';
    }

    public function convertXmlToPhp(string $xml)
    {
        $doc = Document::fromXmlString($xml);

        return $doc->toUnsafeDocument()->textContent;
    }

    public function convertPhpToXml($value): string
    {
        if (\strip_tags((string) $value) !== $value) {
            return '<value><![CDATA['.$value.']]></value>';
        }

        return '<value>'.htmlentities($value).'</value>';
    }
}

This converter will:

  • Check if the string contains HTML tags, if so - it will use CDATA.
  • If not, it will use regular string encoding (with htmlentities)

The strings that are coming in, are currently just being passed as-is.
So if you get HTML back wrapped in CDATA, it will contain the data without any html entities.

Since you will be overwriting base xsd strings with this converter - it is a quite impacting change.
Make sure to test it inside your application broadly :)


An alternative approach, could be the usage of SoapVar instead of a plain string:

'Description'  => new \SoapVar('<ns1:Description><![CDATA[<html><head><title>hello world</title></head></html>]]></ns1:Description>', XSD_ANYXML),

Do note that you need to pass the whole XML tag with a hardcoded namespace. Currently the WSDL only contains one namespace, so that is not a big issue. But if it changes at some point, it might break this logic.

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

dear toon, thanks a lot for your quick reply !!
i agree, that the "TypeConverter" is dangerous in some way.
is there a way to use a "TypeConverter" only for specific XML elements ???

from ext-soap-engine.

veewee avatar veewee commented on August 30, 2024

No, the type-converter has no knowledge of the context it operates on.
It only operates on type:
https://www.php.net/manual/en/soapclient.construct.php#soapclient.construct.options.typemap

As long as your inputs don't (accidentally) contain any HTML tags, it should work just fine with the type converter. It could as well be that the WS accepts CDATA everywhere, making it a non-issue. However, I agree that it would be nicer if they created a custom xsd type for this explicitally in their WSDL.

Since it is something internally in ext-soap, there is nothing we can do about it from this package - until we build our own encoding/decoding system from scratch.

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

what do you think about this idea:

i could implement a comment in my HTML that is only used in "Description", something like:

<!-- USE-CDATA-HERE -->

and instead of

if (\strip_tags((string) $value) !== $value) {

I could search for exactly that (USE-CDATA-HERE) string 🤔

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

that sounds even better, I will run some tests on that 😊

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

@veewee may i ask:

does this code (the typeconverter) has to be placed in the "config" or somewhere else, too ??

from ext-soap-engine.

veewee avatar veewee commented on August 30, 2024

The typemap must be configured on the ExtSoapOptions in the generated factory:
https://github.com/phpro/soap-client/blob/master/docs/cli/generate-clientfactory.md

The config.php in phpro/soap-client is rather to tell code generation how to load the WSDL metadata.
(That logic will be simplified in v3 a bit by using a separate factory for code generation that doesnt take any ext-soap options anymore.)

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

okay, got it. will try, thanks !!

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

@veewee pardon, i have to ask. using "htmlentities" in the "convertPhpToXml" function gives me empty tags when using a string like Test 123 45° - I guess because of the °. so I have to ask: did you maybe mean htmlspecialchars instead of htmlentities 🤔

from ext-soap-engine.

veewee avatar veewee commented on August 30, 2024

htmlentities can take the ENT_QUOTES flag. I've used that function because it handles other special characters besides the regular html once as well. But you can play around with that and see what works for you.

(you could also use DOMDocument to build valid xml - but it seems I haven't got any builder for cdata yet.)

I am a bit confused on why a quote will result in an empty tag though:

<hello>world"</hello>

This is perfectly valid - unless it gets injected in an attribute.

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

The problem seems to be the the "degree" sign (in my example) , I am confused as well. So I switched to "htmlspecialchars" and that worked, because the ° sign doesn't need to be encoded...

I can create a demo repository in case you like to check that.....?

from ext-soap-engine.

michabbb avatar michabbb commented on August 30, 2024

i guess i will stick with the 2nd solution, because it´s too dangerous in my eyes to touch "everything", when there is only one specific tag, that needs to be changed.

@veewee is there any method available to change a specific variable inside a specific class while classes get generated ?
so that this:

public function setDescription(string $Description)
    {
         $this->Description = $Description;
         return $this;
    }

becomes this:

public function setDescription(string $Description)
    {
        if (!empty($Description)) {
            $this->Description  = new SoapVar('<ns1:Description><![CDATA['.$Description.']]></ns1:Description>', XSD_ANYXML);
        }
        return $this;
    }

❓ ❓

from ext-soap-engine.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.