Breve repaso sobre Programación Orientada a Objetos (OOP)
La Programación Orientada a Objetos (OOP, Object Oriented Programming) es una manera de organizar el código que permite a los desarrolladores agrupar tareas similares en clases. Con esta implementación nuestro código se hace más fácil de mantener y evita repeteciones innecesarias (DRY, Don't Repeat Yourself).
Una de las ventajas de OOP es que si modificamos parte de la información en el script, normalmente sólo hace falta cambiarla en un sitio para actualizar el código. Por ejemplo si se ha usado un sistema de bases de datos como MySQL utilizando PDO (PHP Database Objects) y queremos cambiar a otro, los métodos que utilizaremos para las sentencias serán los mismos.
Una clase se puede ver como el esquema de una casa y un objeto como la casa ya construida. Esto significa que en la clase se define su estructura, sus medidas y características y las relaciones entre ellas y el objeto es la casa construida con todos los datos y organización definidos en ella. Se pueden construir las casas (objetos) que se quieran con esa estructura (clase), y cada una tendrá sus propias familias y decoración.
Para definir una clase se utiliza la palabra reservada class, seguida del nombre de clase y dos llaves, entre las cuales se guardará toda la información del esquema. Esta información se guarda en propiedades (así es como se les llama a las variables dentro de las clases), métodos (funciones dentro de las clases) y constantes.
El nombre de la clase puede ser cualquier etiqueta válida siempre que no sea una palabra reservada de PHP. Un nombre válido comienza con una letra o guión bajo, seguido de una cantidad arbitraria de letras, números o guiones bajos.
class NombreClase { // Declaración de una propiedad public $variable = 'Un valor cualquiera'; // Declaración de un método public function mostrarVariable(){ echo $this->variable; } }
$this es una pseudo-variable que está disponible cuando una clase se instancia. La clase instanciada es un objeto, y $this hace referencia a ese objeto. Vamos a ver un ejemplo en el que se ve más claro a qué hace referencia $this:
class ClaseA { function funcionA() { if(isset($this)){ echo '$this está definido, su clase es: '; // La función get_class devuelve el nombre de la clase de un objeto: echo get_class($this) . "<br>"; } else { echo '$this no está definido <br>'; } } } class ClaseB { function funcionB() { // Se llama estáticamente a la función A, pero ésta no es estática // Si E_STRICT está activado generará un aviso ClaseA::funcionA(); } }
Para crear una instancia de una clase, se utiliza la palabra new. Un objeto será creado siempre, a no ser que el objeto tenga un constructor definido y lance una excepción como error. Las clases han de definirse antes de instanciarse.
Introducción a Entity API en Drupal 8/9
Entity System es la API para la manipulación de entidades (CRUD: crear, leer, actualizar, eliminar). La validación de entidades tiene su propia API (que podría validar una entidad guardada a través de REST, en lugar de un formulario, por ejemplo).
El sistema de entidades Drupal 8
En Drupal las entidades son clases con sus respectivos métodos
Ambos tipos están definidos y documentados en interfaces.
Entidad de configuración y entidad de contenido
Los tipos de entidad en el núcleo vienen en dos variantes.
Entidad de configuración (Configuration Entity): Utilizado por el sistema de configuración. Admite traducciones y puede proporcionar valores predeterminados personalizados para las instalaciones. Las entidades de configuración se almacenan dentro de la tabla de la base de datos de configuración común como filas.
Entidad de contenido (Content Entity): Consiste en campos configurables y base, y puede tener revisiones y traducciones de soporte. Las entidades de contenido se almacenan en una tabla de base de datos personalizada como filas. El nombre de la tabla es el mismo que el de la entidad de contenido "id", y las columnas se definen mediante el método "baseFieldDefinitions" de la entidad.
Paquetes (Bundles)
Los paquetes son diferentes variantes de un tipo de entidad. Por ejemplo, con el tipo de entidad de nodo, los paquetes son los diferentes tipos de nodo, como 'artículo' y 'página'.
Normalmente, un paquete está representado por una entidad de configuración, aunque existen otros modelos en los módulos contrib. Entonces, en el ejemplo de nodo, el tipo de nodo 'artículo' es en sí mismo una entidad de configuración. La configuración almacena las diferencias entre los tipos de entidades de contenido, como la configuración y los campos. Al crear un nuevo tipo de entidad que tiene entidades de paquete, creará tanto una Entidad de contenido que administrará los detalles y operaciones del contenido, como una Entidad de configuración que manejará las diferencias entre los tipos de entidad de contenido.
Anotaciones (Annotations):
Al crear un nuevo tipo de entidad, deberá utilizar el sistema de anotaciones integrado en el núcleo. Las anotaciones parecen comentarios de docblock encima de la clase, pero el núcleo de Drupal las analiza y almacena en caché. En muchos sentidos, las anotaciones reemplazan algunos de los ganchos de estilo más antiguos utilizados en Drupal 7.
Analizador de anotaciones (Annotation parser):
Las anotaciones se leen y analizan en tiempo de ejecución mediante un motor de anotaciones. Drupal 8 usa el analizador de anotaciones de Doctrine, que lo convierte en un objeto que PHP puede usar.
Sintaxis: la sintaxis de la anotación está rodeada por @ClassName (), se compone predominantemente de pares clave / valor y puede contener matrices que usan llaves. Las claves de nivel superior no deben estar entre comillas, mientras que las claves de matriz deben hacerlo. Cada par clave / valor debe estar en su propia línea, y esa línea debe terminar con una coma. Ciertas funciones se pueden ejecutar en valores, en particular la función @Translation ().
Ejemplo de sintaxis de anotación que no funciona:
/** * @ContentEntityType( * id = "my_entity_type_id", * label = @Translation("My entity type label"), * example_pair = "this_examples_value", * example_array = { * "array_key" = "array_value", * "some_other_key" = "some_other_value", * }, * ) */
Anotaciones comunes de nivel superior
Manipuladores o (Handlers)
Los controladores se definen en la anotación de la entidad como una matriz. Apoyan a la entidad al mapear ciertas partes de su ejecución a otras clases de PHP. Esas clases "manejarán" las partes asignadas de la ejecución de la entidad.
Almacenamiento (Storage): maneja la carga, el guardado y la eliminación de la entidad. De forma predeterminada, las entidades de contenido usan Drupal \ Core \ Entity \ Sql \ SqlContentEntityStorage mientras que las entidades de configuración usan Drupal \ Core \ Config \ Entity \ ConfigEntityStorage. Puede definir un controlador de almacenamiento para ampliar los métodos de almacenamiento predeterminados de su entidad. Es posible que desee hacer esto para proporcionar métodos adicionales para recopilar los ID de revisión de la entidad o determinar el número de traducciones que tiene una entidad.
Ejemplo: "storage" = "Drupal\node\NodeStorage",
Formulario (Form): en la anotación de controladores de cualquier entidad, hay varios controladores de formularios que asignan los formularios de agregar, editar y eliminar de la entidad a otras clases de PHP.
Ejemplo:
"form" = {
"add" = "Drupal\block\BlockForm",
"edit" = "Drupal\block\BlockForm",
"delete" = "Drupal\block\Form\BlockDeleteForm",
}
Alternativamente, puede definir un formulario "predeterminado" para manejar tanto el formulario de "agregar" como el de "editar" en lugar de definirlos por separado. Vale la pena señalar que el formulario "eliminar" casi siempre será manejado por una clase separada de los otros formularios. Esto se debe a que el formulario de eliminación es generalmente un "formulario de confirmación" que simplemente pregunta si el usuario está seguro de que desea eliminar la entidad.
Creador de vistas (View builder): este controlador proporciona una clase que manejará la salida de la entidad cuando la vea el usuario final. Por ejemplo, al visitar un nodo en un sitio de Drupal 8, la salida de la entidad es manejada por la clase NodeViewBuilder.
Ejemplo: "view_builder" = "Drupal\node\NodeViewBuilder",
Generador de listas (List builder ): la clase del generador de listas manejará la lista de entidades con fines administrativos. Esta clase definirá el contenido de los encabezados, filas y operaciones cuando visite la página de administración de entidades para la entidad. Por ejemplo, al visitar el URI / admin / content de su sitio Drupal, el contenido de la tabla lo proporciona la clase de constructor de listas de la entidad Node.
Ejemplo: "list_builder" = "Drupal\node\NodeListBuilder",
Proveedor de ruta (Route provider): un controlador opcional que, si se implementa, genera rutas para la administración de su entidad. La implementación de este controlador puede reemplazar la necesidad de rutas de entidad definidas en el archivo routing.yml de su módulo. Tenga en cuenta que route_provider funciona junto con los enlaces definidos en su entidad (consulte el ejemplo a continuación en la sección Enlaces). La anotación route_provider es una matriz.
Ejemplo:
"route_provider" = {
"html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
}
Acceso (Access): el controlador de acceso se puede usar para verificar dinámicamente los permisos de su entidad. Es una asignación a una clase que implementa EntityAccessControlHandlerInterface. Core proporciona una implementación de esta interfaz como EntityAccessControlHandler, pero para un control confiable sobre su entidad, querrá extender esa clase con la suya propia.
Datos de vistas (Views data): el controlador views_data permite que una entidad amplíe el módulo Vistas con datos personalizados proporcionados por su entidad. Esto puede ser para agregar baseFieldDefinitions de su entidad como campos de Vistas, unir tablas en relaciones de entidad u otras alteraciones de datos relacionadas con Vistas.
Ejemplo: "views_data" = "Drupal\node\NodeViewsData",
Esquema de almacenamiento (Storage schema): el controlador storage_schema se puede implementar para modificar aún más la configuración de almacenamiento de la base de datos de la entidad. Por ejemplo, agregar índices de tabla adicionales.
Ejemplo: "storage_schema" = "Drupal\node\NodeStorageSchema",
Traducción (Translation): el controlador de traducción se puede utilizar para modificar la forma en que los formularios de su entidad interactúan con las traducciones.
Ejemplo: "translation" = "Drupal\node\NodeTranslationHandler",
Ejemplo completo de Manipuladores (handlers):
El núcleo de Drupal proporciona controladores que puede usar listos para usar, pero en muchos casos querrá extender estas clases con las suyas propias para un mayor control y personalización de su entidad. Este ejemplo muestra una anotación de controladores más completa, utilizando las clases principales que puede ampliar.
handlers = { "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", "list_builder" = "Drupal\Core\Entity\EntityListBuilder", "access" = "Drupal\Core\Entity\EntityAccessControlHandler", "views_data" = "Drupal\views\EntityViewsData", "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", "storage_schema" = "Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema", "translation" = "Drupal\content_translation\ContentTranslationHandler", "form" = { "default" = "Drupal\Core\Entity\ContentEntityForm", "add" = "Drupal\Core\Entity\ContentEntityForm", "edit" = "Drupal\Core\Entity\ContentEntityForm", "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm", }, "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", }, },
Enlaces:
Los enlaces se definen en la anotación de entidad con la sintaxis de matriz. Los enlaces tienen un conjunto específico de claves cuyo valor son URI donde se puede administrar el tipo de entidad o entidades individuales de ese tipo. Tanto las entidades de contenido como las de configuración pueden tener estos enlaces definidos.
Ejemplo:
id = "node", handlers = { "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider" } }, links = { "canonical" = "/node/{node}", "add-page" = "/node/add", "add-form" = "/node/add/{node_type}", "edit-form" = "/node/{node}/edit", "delete-form" = "/node/{node}/delete", "collection" = "/admin/content", },
La creación de estos enlaces no crea automáticamente las rutas para esos URI. Para que estos enlaces sean accesibles, nuestro módulo deberá implementar su propio archivo routing.yml o usar un controlador "route_provider" en la anotación de la entidad.
Enlaces y proveedor de rutas (Links & Route Provider):
Los enlaces anteriores que trabajan junto con un "route_provider" harán que las siguientes rutas nombradas estén disponibles para Drupal.
Uso de enlaces:
Se puede acceder a estos enlaces con el método toUrl () de una entidad:
$view_url_object = $entity->toUrl(); // Default is 'canonical'
$edit_url_string = $entity->toUrl('edit-form')->toString();
Fuente: Página oficial de Drupal