2

I upgraded to magento 2.3.3 but didn't noticed that they changed email classes and zend framework.

I am having a custom module for editing emails in magento admin.

But I am having error:

FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Class 'Zend_Reflection_Class' not found in myfile.php

My code is:

 {
        /**
         * @var VariableResolverInterface
         */
        private $variableResolver;

        public function __construct(
            VariableResolverInterface $variableResolver
        ) {
            $this->variableResolver = $variableResolver;
        }

        /**
         * {@inheritdoc}
         */
        public function getVariables()
        {
            $variables = $this->variableResolver->getOrigVariables();
            $result = [
                [
                    'label' => __('General Variables'),
                    'value' => [
                        [
                            'label' => __('Customer Name'),
                            'value' => __('{{ customer_name }}')
                        ],
                        [
                            'label' => __('Customer Email'),
                            'value' => __('{{ customer_email }}')
                        ],
                        [
                            'label' => __('Customer First Name'),
                            'value' => __('{{ customer_name | split: " " | first }}')
                        ],
                    ]
                ]
            ];

            foreach ($variables as $variable) {
                $variableReflection = new \Zend_Reflection_Class($variable);
                /** @var \Zend_Reflection_Method[] $reflectionMethods */
                $reflectionMethods = $variableReflection->getMethods(\ReflectionMethod::IS_PUBLIC);

                if ($methods = $this->collectMethods($variable, $reflectionMethods)) {
                    $result[] = [
                        'label' => __('%1 Variables', ucfirst($variable->getVariableName())),
                        'value' => $methods
                    ];
                }
            }

            return $result;
        }

        /**
         * Collect all available methods for user.
         *
         * @param VariableInterface         $variable
         * @param \Zend_Reflection_Method[] $reflectionMethods
         *
         * @return array
         * @throws \Zend_Reflection_Exception
         */
        private function collectMethods(VariableInterface $variable, array $reflectionMethods = [])
        {
            $methods = [];
            foreach ($reflectionMethods as $method) {
                if ($this->canUseMethod($method, $variable)) {
                    $docblock = $method->getDocblock();
                    $methodName = $this->convertToLiquid($method->getName());

                    // add methods available in the model object
                    if ($this->isObjectReturned($docblock) && $variable->getNamespace() == $methodName) {
                        $returnType = $docblock->getTag('return')->getType();
                        $variableReflection = new \Zend_Reflection_Class($returnType);
                        $reflectionMethods = $variableReflection->getMethods(\ReflectionMethod::IS_PUBLIC);

                        $methods = array_merge(
                            $methods,
                            $this->collectMethods($variable, $reflectionMethods)
                        );

                        continue;
                    }

                    if ($definition = $this->getMethodDefinition($variable, $method)) {
                        array_unshift($methods, $definition);
                    }
                }
            }

            return $methods;
        }

        /**
         * Determine whether the method can be used or not.
         *
         * @param \Zend_Reflection_Method $method
         * @param VariableInterface       $variable
         *
         * @return bool
         * @throws \Zend_Reflection_Exception
         */
        private function canUseMethod(\Zend_Reflection_Method $method, VariableInterface $variable)
        {
            $canUse = false;
            if (strpos($method->getName(), 'get') === 0 // only getters
                && strpos($method->getDeclaringClass()->getName(), 'AbstractVariable') === false // ignore AbstractClass
                && strpos($method->getDocComment(), '@Suppress') === false // tags without space throw an error
                && $method->getNumberOfRequiredParameters() === 0 // only methods without parameters
                && stripos($method->getDocComment(), '@inheritdoc') === false // ignore methods with "inheritdoc"
                && $method->getDocComment() // skip methods without docblock
            ) {
                $canUse = true;
            }

            return $canUse;
        }

        /**
         * Convert method name to liquid compatible syntax.
         *
         * e.g., "getCouponCode" => coupon_code
         *
         * @param string $methodName
         *
         * @return string
         */
        private function convertToLiquid($methodName)
        {
            $methodWords = preg_split('/(?=[A-Z])/', $methodName); // split name by uppercase letters
            $methodWords = array_filter($methodWords, function($name) { // remove keyword "get" from words
                return $name !== 'get';
            });

            // join remained words with underscore
            return implode('_', array_map('strtolower', $methodWords));
        }

        /**
         * Whether the method return type is object or not.
         *
         * @param \Zend_Reflection_Docblock $docblock
         *
         * @return bool
         *
         */
        private function isObjectReturned(\Zend_Reflection_Docblock $docblock)
        {
            if ($docblock->hasTag('return')) {
                return strpos($docblock->getTag('return')->getType(), '\\') !== false;
            }

            return false;
        }

        /**
         * Get liquid variable definition.
         *
         * @param VariableInterface $variable
         * @param \Zend_Reflection_Method $method
         *
         * @return array
         * @throws \Zend_Reflection_Exception
         * @SuppressWarnings(PHPMD.CyclomaticComplexity)
         */
        private function getMethodDefinition(VariableInterface $variable, \Zend_Reflection_Method $method)
        {
            $definition = [];
            $docblock   = $method->getDocblock();
            $methodName = $this->convertToLiquid($method->getName());
            $namespace  = $docblock->getTag(VariableInterface::DOCBLOCK_TAG_NAMESPACE)
                ? $docblock->getTag(VariableInterface::DOCBLOCK_TAG_NAMESPACE)->getDescription()
                : $variable->getNamespace();

            if ((method_exists($variable, $method->getName())
                    && $method->getDeclaringClass()->getName() === get_class($variable)
                ) || in_array($method->getName(), $variable->getWhitelist())
            ) {
                $value = '';
                if ($docblock->getTag('return')->getType() == 'array'
                    || strpos($docblock->getTag('return')->getType(), '[]') !== false
                ) {
                    $value .= "{% for item in {$namespace}.{$methodName} %}";
                    $value .= "\\n\\n";
                    $value .= "{% endfor %}";
                } else {
                    $filter = $docblock->getTag(VariableInterface::DOCBLOCK_TAG_FILTER)
                        ? $docblock->getTag(VariableInterface::DOCBLOCK_TAG_FILTER)->getDescription()
                        : null;

                    $value = "{{ {$namespace}.{$methodName} ";

                    if ($filter !== null) {
                        $value .= $filter; // add filter to variable
                    }

                    $value .= "}}"; // close variable
                }

                $definition = [
                    'value' => $value,
                    'label' => $docblock->hasTag(VariableInterface::DOCBLOCK_TAG_DESCRIPTION)
                        ? $docblock->getTag(VariableInterface::DOCBLOCK_TAG_DESCRIPTION)->getDescription()
                        : explode("\n", $docblock->getShortDescription())[0]
                ];
            }

            return $definition;
        }
    }

This is happening also with another class:

Zend_Reflection_Method

Anyone can help how can I declare these classes now please?

  • Perhaps \Zend\Code\Reflection\ClassReflection and \Zend\Code\Reflection\MethodReflection – danronmoon Oct 18 at 17:47
  • Regarding mail changes: community.magento.com/t5/Magento-DevBlog/… – danronmoon Oct 18 at 17:48
  • @danronmoon Thank you...Checking your first comment....As for mails, magento team has made huge mistake putting this as a patch....I reverted back some folders because I couldn't send any mail with my third party extensions – G. G. Oct 18 at 17:50
  • You're absolutely correct about this being a mistake. I wish I could offer more comfort about future "patch" releases. – danronmoon Oct 18 at 17:57
  • @danronmoon your fix is not working – G. G. Oct 18 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.