Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

classmap_prefix duplication and other issues with classmaps #106

Open
olegabr opened this issue Dec 21, 2020 · 2 comments
Open

classmap_prefix duplication and other issues with classmaps #106

olegabr opened this issue Dec 21, 2020 · 2 comments

Comments

@olegabr
Copy link

olegabr commented Dec 21, 2020

{
    "name": "ethereumico/ether-and-erc20-tokens-woocommerce-payment-gateway",
    "description": "Ether and ERC20 tokens WooCommerce Payment Gateway enables customers to pay with Ether or any ERC20 or ERC223 token on your WooCommerce store.",
    "type": "project",
    "repositories": [
       {
          "type": "vcs",
          "url": "https://github.com/olegabr/web3.php"
       },
       {
          "type": "vcs",
          "url": "https://github.com/olegabr/php-keccak"
       }
    ],
    "require": {
        "olegabr/web3.php": "~0.1",
        "freemius/wordpress-sdk": "^2.4",
        "woocommerce/action-scheduler": "dev-master"
    },
    "license": "GPLv3",
    "authors": [
        {
            "name": "EthereumICO",
            "email": "[email protected]"
        }
    ],
    "minimum-stability": "dev",
    "require-dev": {
        "coenjacobs/mozart": "dev-master"
    },
    "extra": {
        "mozart": {
            "dep_namespace": "\\Ethereumico\\Epg\\Dependencies\\",
            "dep_directory": "/vendor-epg/",
            "classmap_directory": "/vendor-epg/classes/",
            "classmap_prefix": "ether_and_erc20_tokens_woocommerce_payment_gateway_",
            "packages": [
                "freemius/wordpress-sdk",
                "guzzlehttp/guzzle",
                "guzzlehttp/promises",
                "guzzlehttp/psr7",
                "olegabr/keccak",
                "olegabr/web3.php",
                "paragonie/constant_time_encoding",
                "paragonie/random_compat",
                "phpseclib/phpseclib",
                "psr/http-message",
                "ralouphie/getallheaders",
                "symfony/polyfill-intl-idn",
                "symfony/polyfill-intl-normalizer",
                "symfony/polyfill-mbstring",
                "symfony/polyfill-php72",
                "woocommerce/action-scheduler"
            ],
            "delete_vendor_directories": true
        }
    },
    "scripts": {
        "post-install-cmd": [
            "\"vendor/bin/mozart\" compose",
            "composer dump-autoload"
        ],
        "post-update-cmd": [
            "\"vendor/bin/mozart\" compose",
            "composer dump-autoload"
        ]
    }
}

It created file /home/USER/PROJECT/vendor-epg/classes/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php with contents:

<?php

class ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_Normalizer extends Symfony\Polyfill\Intl\ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_Normalizer\Normalizer
{

Three issues here:

  1. class prefix added 4 times
  2. Symfony\Polyfill\Intl\ namespace is not prefixed with Ethereumico\Epg\Dependencies\
  3. The last namespace before class name is prefixed with class name prefix (4 times of course): ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_ether_and_erc20_tokens_woocommerce_payment_gateway_Normalizer

The /home/USER/PROJECT/vendor-epg/Symfony/Polyfill/Intl/Normalizer/Normalizer.php file is defined correctly as:

<?php

namespace \Ethereumico\Epg\Dependencies\Symfony\Polyfill\Intl\Normalizer;

class Normalizer
@BrianHenryIE
Copy link
Contributor

BrianHenryIE commented Dec 24, 2020

The following ClassmapReplacer.php will skip classnames that already begin with the prefix.

<?php
/**
 * The purpose of this file is to find and update classnames (and interfaces...) in their declarations.
 * Those replaced are recorded and their uses elsewhere are updated in a later step.
 */

namespace CoenJacobs\Mozart\Replace;

class ClassmapReplacer extends BaseReplacer
{

    /** @var string[] */
    public $replacedClasses = [];

    /** @var string */
    public $classmap_prefix;

    public function replace($contents)
    {

        return preg_replace_callback(
            "
	/						# Start the pattern
		namespace\s+[a-zA-Z0-9_\x7f-\xff\\\\]+[;{\s\n]{1}.*?(?=namespace|$) 
							# Look for a preceeding namespace declaration, up until 
							# a potential second namespace declaration
		|					# if found, match that much before repeating the search 
							# on the remainder of the string
		[^a-zA-Z0-9_\x7f-\xff]+			# After a non-class character,
		{$this->classmap_prefix}  		# match an already prefixed classname
		[a-zA-Z0-9_\x7f-\xff]+			# before continuing on the remainder of the string
		|
		(?:abstract\sclass|class|interface)\s+	# Look behind for class, abstract class, interface
		([a-zA-Z0-9_\x7f-\xff]+)		# Match the word until the first 
							# non-classname-valid character
		\s?					# Allow a space after
		(?:{|extends|implements|\n)		# Class declaration can be followed by {, extends, 
							# implements, or a new line
	/sx", // 					# dot matches newline, ignore whitespace in regex.
            function ($matches) use ($contents) {

                // If we're inside a namespace other than the global namesspace, just return.
                if (preg_match('/^namespace\s+[a-zA-Z0-9_\x7f-\xff\\\\]+[;{\s\n]{1}.*/', $matches[0])) {
                    return $matches[0];
                }

	            if (preg_match("/[^a-zA-Z0-9_\x7f-\xff]+{$this->classmap_prefix}[a-zA-Z0-9_\x7f-\xff]+/", $matches[0])) {
		            return $matches[0];
	            }

                // The prepended class name.
                $replace = $this->classmap_prefix . $matches[1];
                $this->saveReplacedClass($matches[1], $replace);
                return str_replace($matches[1], $replace, $matches[0]);
            },
            $contents
        );
    }

    public function saveReplacedClass($classname, $replacedName)
    {
        $this->replacedClasses[ $classname ] = $replacedName;
    }
}

It is PR #101 with this added:

[^a-zA-Z0-9_\x7f-\xff]+			# After a non-class character,
{$this->classmap_prefix}  		# match an already prefixed classname
[a-zA-Z0-9_\x7f-\xff]+			# before continuing on the remainder of the string
|

Updating Replacer.php:125 to :

'/(.*)([^a-zA-Z0-9_\x7f-\xff\\\\])'. $original . '([^a-zA-Z0-9_\x7f-\xff])/U',

fixes the extends incorrect replacement but needs a bit more thought and testing before making a PR.

PhpStorm was highlighting the namespace in Symphony/Polyfill/Intl/Normalizer/Normalizer.php with "undefined namespace Intl" and "undefined constant Normalizer". I changed composer.json's "dep_namespace": "\\Ethereumico\\Epg\\Dependencies\\", to "dep_namespace": "Ethereumico\\Epg\\Dependencies\\", and the message went away.

@coenjacobs
Copy link
Owner

That PR that was referred above is now released as part of Mozart 0.6.0. @olegabr can you confirm this is now resolved?

BrianHenryIE referenced this issue in BrianHenryIE/strauss Feb 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants