Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. OpenCart
Code

Decodificando la Clase Proxy en OpenCart

by
Difficulty:IntermediateLength:MediumLanguages:

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Más seguido que no, damos las cosas por hecho. Si algo está funcionando como se espera, no nos molestamos en los funcionamientos internos de ello para entender el mecanismo que yace abajo. O para ponerlo de otro modo, ¡no nos adentramos a algo hasta que estamos en algún tipo de problema!

De manera similar, siempre me estuve preguntando sobre un par de conceptos en OpenCart que eran usados en el framework que yace abajo, y uno de ellos era la clase Proxy. Me tomó un tiempo entenderla, y pensé que era algo grandioso para compartir contigo ya que siempre es divertido saber algo nuevo.

¿Qué Es una Clase Proxy?

Aunque encontrarás varios materiales en línea que definen el término proxy, la definición desde Wikipedia es sorprendente y fácil de entender.

Un proxy, en su forma más general, es una clase funcionando como una interface para algo más.

Así que el proxy delega el control al objeto que pretende usar, y así actúa a nombre de la clase que está instanciada. De hecho, el patrón de diseño del proxy es un patrón muy popular que es usado por frameworks populares si es necesario. Considerando el hecho de que una discusión del método proxy en si mismo es un tema tan amplio y fuera del alcance de este artículo, resumiré rápidamente lo que es usado la mayoría del tiempo:

  • Actúa como en envoltorio para proporcionar funcionalidad adicional.
  • Retrasa la instalación de objetos costosos, también referenciado como lazy loading.

En el contexto de OpenCart, podríamos decir que el patrón de proxy es usado para agregar funcionalidad a la clase proxy base. Habiendo dicho eso, ¡la clase proxy por si misma no proporciona nada excepto un par de métodos mágicos! Como veremos en la siguiente sección, la clase proxy es enriquecida en tiempo de ejecución adjuntando propiedades a esta.

Antes de que nos movamos a la siguiente sección, echemos un vistazo rápido a la clase proxy. Esta reside en system/engine/proxy.php.

Como puedes ver, esta implementa tres métodos mágicos: __get()__set(), y __call(). Entre estos, la implementación del método __call() es una importante, y volveremos a esta muy pronto.

Cómo Funciona la Clase Proxy Con el Modelo

En este sección, explicaré cómo funciona exactamente una llamada como $this->model_catalog_category->getCategory($category_id) fuera de la caja.

De hecho, la historia comienza con la siguiente declaración.

Durante el proceso de boostraping, el framework OpenCart almacena todos los objetos genéricos al objeto Registry para que puedan ser recuperados a voluntad. Como resultado de eso, la llamada $this->load devuelve el objeto Loader del Registro.

La clase Loader proporciona varios métodos para cargar diferentes componentes, pero en lo que estamos interesados aquí es el método modelo. Saquemos rápidamente el pedazo de código del método model desde system/engine/loader.php.

Considerando el ejemplo citado, el valor del argumento $route es catalog/category. Primero, el valor de la variable $route es limpiado, y después de eso dispara el evento before para permitir a otros listeners de módulo cambiar el valor de la variable $route.

Después, este revisa la existencia del objeto modelo solicitado en el Registro. Si el Registro contiene el objeto solicitado, no se necesita más procesamiento.

Si el objeto no es encontrado, este sigue un procedimiento interesante para cargarlo, y es el pedazo de código que estamos buscando en el contexto de este artículo.

Para comenzar, este prepara la ruta del archivo del modelo solicitado y lo carga si existe.

Seguido de eso, instancía el objeto Proxy.

Ahora, pon atención al siguiente ciclo for---hace más de lo que parece.

En nuestro caso, el valor de $class debería ser ModelCatalogCategory. El pedazo de código get_class_methods($class) carga todos los métodos de la clase ModelCatalogCategory y cicla a través de esta. ¿Qué hace en el ciclo? Veamos más de cerca.

En el ciclo, este llama al método callback de la misma clase. Es interesante notar que el método callback devuelve la función callable que es asignada al objeto $proxy con la llave como el nombre de método. Por supuesto, el objeto proxy no tiene ninguna propiedad; será creado al vuelo usando el método mágico __set()!

Después, el objeto $proxy es agregado al Registro para que pueda ser traído después cuando sea necesario. Echa un vistazo más de cerca al componente clave el método set. En nuestro caso, debería ser model_catalog_category.

Al final, llamaré al evento after para permitir a otros listeners de módulo cambiar el valor de la variable $route.

Esa es una parte de la historia.

Vayamos a través de lo que sucede exactamente cuando usas lo siguiente en tu controlador.

El pedazo de código $this->model_catalog_category intenta encontrar una coincidencia para la llave model_catalog_category en el Registro. Si te estás preguntando cómo, solo vira la definición de la clase Controller en el archivo system/engine/controller.php---esta proporciona el método mágico __get() que lo hace.

Como acabamos de discutir, eso debería revolver el objeto $proxy que es asignado a esa llave particular. Después, intenta llamar al método getCategory en ese objeto. Pero la clase Proxy no implementa tal método, ¿así que cómo va a funcionar eso?

¡El método mágico __call() viene al rescate! Siempre que llamas a un método que no existe en la clase, el control es transferido al método mágico __call().

Exploremoslo a detalle para entender que está pasando. Abre el archivo de clase Proxy y pon atención a ese método.

El $key contiene el nombre de la función que está siendo llamada--getCategory. Por el otro lado, $args contiene argumentos pasados al método, y debería ser un arreglo de un elemento conteniendo el id de categoría que está siendo pasado.

Después, hay un arreglo $arg_data que almacena referencias de argumentos. Francamente, no estoy seguro si el código $arg instanceof Ref tiene algún sentido o no ahí. Si alguien sabe por qué está ahí, estaría feliz de saber.

Además, este intenta revisar la existencia de la propiedad $key en el objeto $proxy, y este resulta en algo como esto.

Recuerda que anteriormente asignamos todos los métodos de la clase ModelCatalogCategory como propiedades del objeto $proxy usando un ciclo for. Para tu conveniencia, pegaré ese código de nuevo. 

Así que debería estar ahí, ¡y también debería devolvernos la función callable! Y finalmente, este llama a esa función callable usando la función call_user_func_array pasando la función callable misma y los argumentos de método.

Ahora, desviemos nuestra atención a la definición de la función callable misma. Tomaré el pedazo de código del método callback definido en system/engine/loader.php.

Ya que es una función anónima, ha preservado los valores en la forma de variables $registry y $route que fueron pasadas anteriormente al método callback. En este caso, el valor de la variable  $route debería ser catalog/category/getCategory.

Aparte de eso, si vemos el pedazo de código importante en esa función, esta instancía el objeto ModelCatalogCategory y lo almacena en un arreglo estático $model.

Y aquí está un pedazo de código que toma el nombre de método que necesita ser llamado usando la variable $route.

Así que tenemos una referencia de objeto y un nombre de método que nos permite llamarlo usando la función call_user_func_array. ¡El siguiente pedazo de código hace justo eso!

Al final del método, el resultado es devuelto vía la variable $output. Y sí, ¡esa es otra parte de la historia!

He ignorado intencionalmente el código de eventos pre y post que te permite anular métodos de las clases nucleares de OpenCart. Usando eso, podrías anular cualquier método de clase nuclear y modificarlo de acuerdo a tus necesidades. Pero dejemos eso para otro día, ¡ya que será mucho que poner en un solo artículo!

Así que así es como funciona todo junto. Espero que estés más seguro sobre esas llamadas OpenCart y sobre sus funcionamientos internos.

Conclusión

Lo que hemos discutido hoy es uno de los conceptos interesantes y ambiguos en OpenCart: el uso del método Proxy en un framework para soportar convenciones para llamar a métodos modelo. Espero que el artículo fuera lo suficientemente interesante y haya enriquecido tu conocimiento del framework OpenCart.

Me encantaría tener tu retroalimentación sobre esto, y si sientes que debería cubrir tales temas en mis siguientes artículos, ¡no dudes en dejar un comentario acerca de eso!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.