Jump to content

Prestashop 8 adminControllers y Configuration deprecated


Recommended Posts

Hola

Estos días he subido a la versión 8.2 y ando revisando el código de mis módulos eliminando llamadas a métodos "deprecated" y me he encontrado con un problema curioso.

En mis controladores del administrador (heredan de FrameworkBundleAdminController) tengo un método "__construct"  que inicializa el logger del módulo usando una variable de configuración que siempre había leído con:

$this->configuration->get()

Esto funcionaba porque en el constructor de la clase padre teníamos:

$this->configuration = new Configuration();

con lo que el parent::__construct() nos garantizaba la inicialización de la variable. Pero ahora tenemos que el constructor de FrameworkBundleAdminController es

    public function __construct()
    {
        @trigger_error(__FUNCTION__ . ' is deprecated since version 8.1 and will be removed in the next major version.', E_USER_DEPRECATED);

        $this->configuration = new Configuration();
    }

y nos sugieren que empleemos:

@deprecated since version 8.1, use $this->getConfiguration() instead

Pero si cambio mi método, me encuentro que se produce un error

imagen.png.059a5475318d848023d5f20a8b352d24.png

y revisando linea a linea resulta que esa llamada a $this->getConfiguration() ejecuta

   /**
     * @return ShopConfigurationInterface
     */
    protected function getConfiguration(): ShopConfigurationInterface
    {
        return $this->container->get('prestashop.adapter.legacy.configuration');
    }

Pero $this->container es NULL!!!

Es decir, no puedo llamar a configuration en el constructor del controlador porque aún no está seteado el contenedor de Symfony.

La solución aquí sería pasar el objeto configurador directamente como parámetro al constructor, pero me da rabia ya que debería de tenerlo ya disponible si el padre se inicializase. ¿Por que han descartado el constructor del padre?

Y ya que estamos, alguien sabe como se puede ahora hacer esto?

                $productProvider = $this->get('prestashop.adapter.data_provider.product');
                $product = $productProvider->getProduct($id,false,$lang);

Esta clase "ProductDataProvider" ha sido marcada deprecated pero no he encontrado una sustituta válida....

 

Link to comment
Share on other sites

Entiendo que el deprecated  de ProductDataProvider viene por la próxima implementación del patrón CQRS con el CommandBus y el QueryBus para modificar información de  objeto y para acceder a la información del objeto

use PrestaShop\PrestaShop\Core\Domain\Product\Command\AddProductCommand;
use PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductForEditing;

En el  Controller/Admin/FrameworkBundleAdminController.php están los métodos

getCommandBus()
getQueryBus()

 

Puede que sea mejor utilizar

$configuration = $this->getConfiguration(); 

en algún método de acción del extend de FrameworkBundleAdminController.

indexAction
formAction

Entiendo que los cambios se deben también al proceso de migración a patrones mas estrictos de inyección de dependencias, que seria lo que comentas de pasar la configuración a través del constructor para aceptar una instancia de Configuration. Registrando el controlador como un servicio en el  services.yml

Link to comment
Share on other sites

Hola @ventura

Efectivamente. El problema es que si uso por ejemplo:

                /* Lo intentamos con el querybus */
                /* @var ProductFormDataProvider $productProvider */
                $queryBus = $this->get('prestashop.core.query_bus');
                $productProvider = new ProductFormDataProvider(
                    $queryBus, $this->getConfiguration(), $this->getContextLangId(), $this->getContextShopId(),null);
                $product = $productProvider->getData($id);

Esto me devuelve un array en lugar de un objeto Product que es lo que aún necesita recibir el método updateQuantity de StockManager por lo que realmente  ahora mismo veo que está todo aún con fuerte dependencia del ObjectModel antiguo. Y me sorprende ya que esta clase está supuestamente ya migrada y reside en:

PrestaShop\PrestaShop\Core\Stock\StockManager

Por eso la use... pensaba que estaba trabajando en la parte symfony pero parece ser que no del todo.

No lo toco por ahora y espero a ver la versión 9 como lo hace.

Gracias!

NOTA: Perdón, por dar contexto pongo el trozo de código en el que tengo el problema ya que con lo expuesto no se entiende nada. En una clase de servicio, manipulo el stock de un producto. Para ello:

           $psStock = new StockManager();
            $id_shop = $this->configuration->get('PS_SHOP_DEFAULT',1,null);
            // Sacamos el producto
            $sfContainer = SymfonyContainer::getInstance();
            if (null === $sfContainer) {
                $this->logger->Log("changeStock -> Fallo al cargar el container para obtener el producto!",'ERROR');
                return $ret;
            }
            try {
                // MANOLO: TODO Hay que quitar este deprecated ¿COMO? No actualizar a 9 sin quitarlo!
                $productProvider = $sfContainer->get('prestashop.adapter.data_provider.product');
                $product = $productProvider->getProduct($stockObj->getIdProduct());
                // Debemos ver que forma tiene este método en la V9 ya que el actual espera un Product legacy
                $psStock->updateQuantity($product, $stockObj->getIdProductAttribute(), $qty, $id_shop, true);
            } catch (ServiceNotFoundException $e){
                $this->logger->Log("changeStock -> No encuentro el servicio 'prestashop.adapter.data_provider.product'. El stock de almacenes y de prestashop podría haberse desincronizado en "
                    . $qty . " unidades para id_stock " . $id_stock . ". Producto (" . $stockObj->getIdProduct() . "," . $stockObj->getIdProductAttribute() . ")",'WARN');
            }
/* Fin sincronización con stock Prestashop */

 

Edited by Manuel_GT (see edit history)
Link to comment
Share on other sites

La clase StockManager tiene todavia mucho acoplamiento con el ObjectModel del producto. 

El ProductFormDataProvider devuelve un DTO (Data Transfer Object) que entiendo que será el formato de estructura de datos que se utilizara en vez del ObjectModel.

Un saludo.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...