Cómo simplificar una relación Many-To-Many consigo misma

En esta breve entrada expongo cómo el programador puede facilitarse un poco su actividad cuando en Doctrine establezca una relación de una entidad consigo misma. El código que se expone es de una entidad del framework Symfony, pero fácilmente se puede adaptar a cualquier entorno PHP donde, eso sí, se esté empleando este conocido ORM.

Según la documentación de Doctrine, el código para la relación Many-To-Many (de muchos a muchos) de una entidad que se referencia a si misma, por ejemplo un producto que puede tener otros productos relacionados, sería:

class Product
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ManyToMany(targetEntity="Product", mappedBy="myProducts")
     */
    private $relatedWithMe;

    /**
     * @ManyToMany(targetEntity="Product", inversedBy="relatedWithMe", fetch="EAGER")
     * @JoinTable(name="related_products",
     *      joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="related_product_id", referencedColumnName="id")}
     *      )
     */
    private $myProducts;

    public function __construct()
    {
        $this->relatedWithMe = new ArrayCollection();
        $this->myProducts = new ArrayCollection();
    }

    public function addRelatedWithMe(Product $relatedWithMe): self
    {
        if (!$this->relatedWithMe->contains($relatedWithMe)) {
            $this->relatedWithMe[] = $relatedWithMe;
            $relatedWithMe->addMyProduct($this);
        }

        return $this;
    }

    public function removeRelatedWithMe(Product $relatedWithMe): self
    {
        if ($this->relatedWithMe->contains($relatedWithMe)) {
            $this->relatedWithMe->removeElement($relatedWithMe);
            $relatedWithMe->removeMyProduct($this);
        }

        return $this;
    }

    /**
     * @return Collection|Product[]
     */
    public function getMyProducts(): ?Collection
    {
        return $this->myProducts;
    }

    public function addMyProduct(Product $myProduct): self
    {
        if (!$this->myProducts->contains($myProduct)) {
            $this->myProducts[] = $myProduct;
        }

        return $this;
    }

    public function removeMyProduct(Product $myProduct): self
    {
        if ($this->myProducts->contains($myProduct)) {
            $this->myProducts->removeElement($myProduct);
        }

        return $this;
    }

Sigue leyendo

i elevado a i

Una serie de artículos acerca de la exponenciación con números complejos, que di por finalizada en su tercera entrega, y a los que el lector puede recurrir si no entiende algo de lo que en el presente artículo se explica, voy a ampliarla para el curioso caso de ii, y digo curioso pues el resultado es un número real.

Vimos que la generalización de la exponenciación, ab, sean a y b reales1 o complejos, es:

Exponenciación generalizada

En el presente caso, a = i, y si bien el logaritmo complejo existe, aplicando la fórmula de Euler, podremos obtener la forma exponencial para calcular fácilmente ii. En primer lugar, vamos a expresar i en forma polar para obtener dos datos que necesitaremos: el módulo y el argumento. El módulo, obviamente, será 1 y el argumento será π/2 radianes, pues i forma un ángulo recto con la parte real o eje de las ordenadas:

El número imaginario en el plano cartesiano complejo

Sigue leyendo

Ecuación de la asíntota oblicua

Es frecuente que a los alumnos se les enseñe que, si una función tiene un asíntota oblicua que viene dada por y = ax + b, los términos a y b se calcularán a partir de dos fórmulas que deben memorizar:

término b

(1)

término a

(2)

Pero, ¿de dónde provienen? Si tenemos poca memoria y/o preferimos entender el porqué de las cosas, algo bastante conveniente en matemáticas, debemos tener en cuenta que, para una x infinitamente grande, por las propiedades de los límites, se cumplirá f(x) – y = 0:

ecuación asintota oblicua

(3)

Sigue leyendo

La Inteligencia Artificial como último legado del ser humano

En este artículo divago, sin pretensión, sobre diferentes temas que me han interesado a lo largo de la vida: la finitud de la misma (tanto la individual como la del conjunto de los seres de este planeta), las distancias insalvables del espacio y su hostilidad a la vida, el sentido de esta… y la informática. Desde luego, el ser humano es algo más que inteligencia, así como para la vida la inteligencia es sólo una herramienta más, como las garras y los dientes o la capacidad de ver de noche, pero a largo plazo, tal vez sea lo único que podamos hacer perdurar.

El planeta tierra no podrá sustentar indefinidamente la vida, especialmente las formas de vida más complejas, como la nuestra, que son también las más delicadas: tenemos mucha menos resistencia que, por ejemplo, las cucarachas, y estás a su vez se quedan cortas frente a determinadas bacterias y virus, algunos capaces de permanecer latentes durante siglos antes de volver a despertar. Ahora mismo, nuestra civilización se enfrenta a dos grandes problemas:

Sigue leyendo

Redimensión de imágenes proporcionalmente en PHP

Una necesidad que surge en todas las webs cuyos contenidos son introducidos por un usuario (o varios) a través de un gestor de contenidos, es adaptar las imágenes que estos suben al diseño de la misma para que no se deforme. Además, las proporciones de una imagen en una sección pueden ser diferentes a cómo se muestra en otra; un caso típico es usar una proporción para un listado y otra para la ficha de cada elemento, por ejemplo las noticias, los productos, etc.

Para resolver este problema sirve el conjunto de clases PHP que presentó en este artículo. Este software, a partir de una imagen original, creará una copia por cada tamaño que necesitemos. El proyecto completo puede verse en Github y el objetivo del presente artículo es explicar cómo funciona. En primer lugar, instanciamos la clase:

$objResize = Signia_ImageResize_Factory::getInstanceOf($srcFile, $destFile, $newSize);

Donde:

  • $srcFile es el path hacia la imagen que ha subido el usuario.
  • $desFile es el path de la imagen de destino.
  • $newSize es el tamaño deseado.

A partir de un array con los tamaños deseados podemos crear un bucle por cada uno de ellos ($newSize). Los índices widthMaxheigthMax hacen referencia al tamaño máximo permitido, mientras que width y height pueden entenderse como widthMin y heightMin. Veamos un ejemplo:

$imageType = [
  'slide' => ['width' => 1000, 'widthMax' => 1000, 'height' => 400, 'heightMax' => 400, 'background' => '000000'],
  'r2_34' => ['width' => 468, 'widthMax' => 2340, 'height' => 200, 'heightMax' => 1000],
  'r2_7'  => ['width' => 1080, 'widthMax' => 2700, 'height' => 400, 'heightMax' => 1000],
  'r1_6'  => ['width' => 459, 'widthMax' => 1000, 'height' => 287, 'heightMax' => 625],
  'r1'    => ['width' => 266, 'widthMax' => 266, 'height' => 177, 'heightMax' => 177]
];

En Factory.php podemos ver la clase Signia_ImageResize_Factory:

class Signia_ImageResize_Factory
{
	static public function getInstanceOf($srcImageName, $destImageName, $newSize)
	{
		$aux       = explode(".", $destImageName);
		$extension = end($aux);
		if (preg_match("/jpg|JPG|jpeg|JPEG/", $extension)) {
			$extension = "jpeg";
		}
		$imageResizer = "Signia_ImageResize_" . ucfirst($extension);

		return new $imageResizer($srcImageName, $destImageName, $newSize);
	}
}

Sigue leyendo